C# in Async Task change Label Text

主宰稳场 提交于 2019-12-19 04:10:52

问题


The following Code does not change the Text and stops executing the Task

private void button1_Click(object sender, EventArgs e)
    {
        label1.Text = "Test";
        Task.Run(() => MyAsyncMethod());
    }

    public async Task MyAsyncMethod()
    {
        label1.Text = "";
        //everything from here on will not be executed
    }

would be really handy if you could use async together with the UI


回答1:


for accessing a GUI control through a second thread you need to invoke. following example shows how to set a label's text properly

  private void setLabel1TextSafe(string txt)
  { 
       if(label1.InvokeRequired)
           label1.Invoke(new Action(() => label1.Text = txt));
       else
           label1.Text = txt;
  }

I hope this solves your problem




回答2:


would be really handy if you could use async together with the UI

The design of async was carefully done so you can use it naturally with the UI.

in my code i run a function that does a lot of IO and stuff that takes a long time

If you have asynchronous I/O methods (which you should), then you can just do this:

private async void button1_Click(object sender, EventArgs e)
{
  label1.Text = "Test";
  await MyMethodAsync();
}

public async Task MyMethodAsync()
{
  label1.Text = "";
  await ...; // "lot of IO and stuff"
  label1.Text = "Done";
}

That's the most natural approach.

However, if you need to run code on a background thread (e.g., it's actually CPU-bound, or if you just don't want to make your I/O operations asynchronous like they should be), then you can use IProgress<T>:

private void button1_Click(object sender, EventArgs e)
{
  label1.Text = "Test";
  var progress = new Progress<string>(update => { label1.Text = update; });
  await Task.Run(() => MyMethod(progress));
}

public void MyMethod(IProgress<string> progress)
{
  if (progress != null)
    progress.Report("");
  ...; // "lot of IO and stuff"
  if (progress != null)
    progress.Report("Done");
}

Under no circumstances should modern code use Control.Invoke or (even worse) Control.InvokeRequired.




回答3:


Task.Run is used to envelope an Action (that is not async) into a Task. Any Task that you want to execute should be awaited. Thus, that Task.Run of yours is rigorously doing nothing.

Mark that button1_Click event handler of yours as async. Then remove that Task.Run and instead do await MyAsyncMethod().




回答4:


Try this. You don't need to fire a new thread to invoke the async method. compiler will do it for you.

private void button1_Click(object sender, EventArgs e)
    {
        label1.Text = "Test";
        MyAsyncMethod();
    }
public async Task MyAsyncMethod()
{
    return await Task.Run(() =>{
    label1.Text = "";
    //everything from here on will not be executed
     }
}



回答5:


I think both the questions and some of the answers are not clear. Depending on where in the task thread you need to update the label you have to use invoke. Otherwise you can leverage await and leverage the standard semantics.

    private async void button1_Click(object sender, EventArgs e)
    {
        label1.Text = "Starting to run a long task... carry on...";
        await snooze(3);
        label1.Text = "Done with long task";
    }

    public Task<int> snooze(int seconds)
    {
        label1.Text = "zzzz...";
        return Task.Run(
        () => {
            label1.Invoke(new Action(() => label1.Text = "For some reason I need to alert you here.. bad dream perhaps...direct access to label1 will fail"));
            Thread.Sleep(seconds * 1000);
            return  seconds;
           });

    }


来源:https://stackoverflow.com/questions/30281387/c-sharp-in-async-task-change-label-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!