async/await的实质
其实.NET 4.5的async和await就是一个语法糖而已,完全可以使用XXXXXXXntinueWith(t => { ... });实现,这样用lambda表达式的闭包特性即可实现异步编程。
async和await存在的必要性还是有的。比如说可以在循环内await,非常方便。而使用闭包进行异步编程的话,作用域会被分割,对于顺序执行和条件执行还好说,对于循环,编写起来是比较困难的(当然也并不是没有办法)。await解决了这些问题。
<code class="lang-c">using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
namespace mywinforms1234
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
async Task<int> asyncmethod()
{
await Task.Delay(1000);
return 1;
}
void Button1Click(object sender, EventArgs e)
{
Task<int> a = asyncmethod();
a.ContinueWith(t => {
MessageBox.Show(t.Result.ToString());
});
}
}
}</int></int></code>
如果用纯粹的lambda代码实现asyncmethod,应该是这样的:
<code class="lang-c">Task<int> asyncmethod()
{
return Task.Delay(1000).ContinueWith(t => {
return 1;
});
}</int></code>
和await不同的是,
无论是GUI程序还是控制台程序,ContinueWith都是在新线程中继续执行的。在GUI程序中,要想达到像await一样的效果(插入到主线程的消息循环中继续执行),需要在第二个参数加上XXXXXXXXXXXXXXXXomCurrentSynchronizationContext(),这样的话操作GUI部件便不会报错。
<code class="lang-c">void Button1Click(object sender, EventArgs e)
{
Task<int> a = asyncmethod();
a.ContinueWith(t => {
MessageBox.Show(t.Result.ToString() + " " + Thread.CurrentThread.ManagedThreadId);
Text = "finished";
}, TaskScheduler.FromCurrentSynchronizationContext());
}</int></code>