async/await简化多线程调用主界面控件方法
1.C#4.0的做法
C#4.0调用多线程多为Task操作,一般将耗时的工作交给后端线程去做,主线程只需要保持数据更新就行了。后端线程无法直接控制主界面的线程,一般是通过调用主界面的句柄,Invoke/BeginInvoke这两个方法,一个同步,一个异步方法。这样会导致很多不方便的地方。这里展示一个示例:
private void btn_Click(object sender, EventArgs e)
{
Task.Run(() =>
{
string url = "https://www.baidu.com/";
this.Invoke((Action)(() => this.btnAsync.Enabled = false));
using (var client = new HttpClient())
{
client.GetStringAsync(url);
}
this.Invoke((Action)(() => this.btnAsync.Enabled = true));
});
}
可以看到在后台线程中多次与主线程相互交叉,增加编程难度。
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
2C#5.0中的异步
C#5.0的这个主要特性基于TPL,因此可以在适用于异步的地方编写同步形式的代码。它包含一个新的语言构造,可以await等待一个异步的操作,但实际上它并没有阻塞当前执行线程。当程序运行到await时,会立即返回调用者,等到task结束时,调用task后面的代码,控件之间的跨线程调用也没有了。
async private void btnAsync_Click(object sender, EventArgs e)
{
this.btnAsync.Enabled = false;
Task task = Task.Run(async () =>
{
string url = "https://www.baidu.com/";
using (var client = new HttpClient())
{
await client.GetStringAsync(url);
}
});
await task;
this.btnAsync.Enabled = true;
}