异步任务中的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 } 

如果您可以与UI一起使用异步,那将非常方便

通过您需要调用的第二个线程访问GUI控件。 以下示例显示如何正确设置标签的文本

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

我希望这能解决你的问题

如果您可以与UI一起使用异步,那将非常方便

async的设计经过精心设计,因此您可以在UI中自然使用它。

在我的代码中,我运行一个function,可以执行大量的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

 private void button1_Click(object sender, EventArgs e) { label1.Text = "Test"; var progress = new Progress(update => { label1.Text = update; }); await Task.Run(() => MyMethod(progress)); } public void MyMethod(IProgress progress) { if (progress != null) progress.Report(""); ...; // "lot of IO and stuff" if (progress != null) progress.Report("Done"); } 

在任何情况下,现代代码都不应使用Control.Invoke或(甚至更糟) Control.InvokeRequired

Task.Run用于将Action(不是异步)封装到Task中。 应该等待您要执行的任何任务。 因此,你的Task.Run严格无所事事。

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

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

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

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

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