sav*_*eff 3 c# user-interface label asynchronous 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
}
Run Code Online (Sandbox Code Playgroud)
如果你可以与UI一起使用异步,那将会非常方便
Ste*_*ary 10
如果你可以与UI一起使用异步,那将会非常方便
设计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";
}
Run Code Online (Sandbox Code Playgroud)
这是最自然的方法.
但是,如果您需要在后台线程上运行代码(例如,它实际上是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");
}
Run Code Online (Sandbox Code Playgroud)
在任何情况下,现代代码都不应使用Control.Invoke或(甚至更糟)Control.InvokeRequired.
通过您需要调用的第二个线程访问GUI控件.以下示例显示如何正确设置标签的文本
private void setLabel1TextSafe(string txt)
{
if(label1.InvokeRequired)
label1.Invoke(new Action(() => label1.Text = txt));
else
label1.Text = txt;
}
Run Code Online (Sandbox Code Playgroud)
我希望这能解决你的问题