用户界面- c#在异步任务中更改标签文本



以下代码不改变文本并停止执行任务

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
    }
如果你能将async和UI一起使用
,那么

将会非常方便。

如果你能在UI 中同时使用async,那么

将会非常方便。

async的设计是精心设计的,所以你可以与UI自然地使用它。

在我的代码中,我运行了一个函数,它做了很多IO和需要很长时间的东西

如果您有异步I/O方法(您应该这样做),那么您可以这样做:

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";
}

这是最自然的方法。

然而,如果你需要在后台线程上运行代码(例如,它实际上是cpu绑定的,或者如果你只是不想让你的I/O操作异步,那么你可以使用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");
}

现代代码在任何情况下都不应该使用Control.Invoke或(更糟糕的)Control.InvokeRequired

用于通过需要调用的第二个线程访问GUI控件。下面的例子展示了如何正确设置标签的文本

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

我希望这能解决你的问题

Task.Run用于将Action(非异步)封装到Task中。任何您想要执行的任务都应该等待。因此,你的Task.Run严格地什么都不做。

button1_Click事件处理程序标记为async。然后删除Task.Run,而等待MyAsyncMethod()

试试这个。您不需要触发一个新线程来调用异步方法。编译器会为你做的。

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
     }
}

我认为问题和一些答案都不清楚。根据任务线程中需要更新标签的位置,必须使用invoke。否则,您可以利用await和标准语义。

    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;
           });
    }

相关内容

  • 没有找到相关文章

最新更新