我读过埃里克·利珀特的article http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx about async
,以及人们的困惑async
关键词。他说 :
it (async
) 表示“该方法包含涉及等待的控制流
异步操作,因此将被重写
编译器进入连续传递风格以确保
异步操作可以在正确的位置恢复此方法。”异步方法的重点是尽可能留在当前线程上
我不明白这一点。如果我执行一个异步方法(Task
)并且它运行,它surely在另一个线程上运行。
而且,如果我写一个方法使用await
,(恕我直言)它释放了正常的控制流,代码是重构的一样 ”ContinueWith
“ 稍后的another thread.
我用(控制台)测试了它:
/*1*/ public void StartChain()
/*2*/ {
/*3*/ var a = FuncA();
/*4*/ Console.WriteLine(a.Result);
/*5*/ }
/*6*/
/*7*/ public async Task < int > FuncA()
/*8*/ {
/*9*/ Console.WriteLine("A--" + Thread.CurrentThread.ManagedThreadId);
/*10*/ var t = await FuncB();
/*11*/ Console.WriteLine("B--" + Thread.CurrentThread.ManagedThreadId);
/*12*/ return t;
/*13*/ }
/*14*/
/*15*/ public async Task < int > FuncB()
/*16*/ {
/*17*/ Console.WriteLine("C--" + Thread.CurrentThread.ManagedThreadId);
/*18*/ await Task.Delay(2000);
/*19*/ Console.WriteLine("D--" + Thread.CurrentThread.ManagedThreadId);
/*20*/ return 999;
/*21*/ }
/*22*/
/*23*/ void Main()
/*24*/ {
/*25*/ StartChain();
/*26*/ }
/*27*/
结果是:
A--7
C--7
D--17 <-----D and B are on different thread
B--17
999
那么埃里克所说的“留在当前线程”是什么意思呢?
edit 1:
in asp.net
它还返回不同的线程ID。
public async Task<int> FuncA()
{
Response.Write("<br/>C----" + Thread.CurrentThread.ManagedThreadId);
var t = await FuncB();
Response.Write("<br/>D----" + Thread.CurrentThread.ManagedThreadId);
return t;
}
public async Task<int> FuncB()
{
Response.Write("<br/>E----" + Thread.CurrentThread.ManagedThreadId);
await Task.Delay(2000);
Response.Write("<br/>F----" + Thread.CurrentThread.ManagedThreadId);
return 999;
}
protected async void Page_Load(object sender, EventArgs e)
{
Response.Write("<br/>A----" + Thread.CurrentThread.ManagedThreadId);
var a=await FuncA();
Response.Write("<br/>B----" + Thread.CurrentThread.ManagedThreadId);
}
A----8
C----8
E----8
F----9
D----9
B----9
edit 2
(得到答复后)
看来线程只在 GUI 应用程序中提供服务:.我在 winform 中运行这段代码
public async Task<int> FuncA()
{
textBox1.Text +=Environment.NewLine+ "\nC----" + Thread.CurrentThread.ManagedThreadId;
var t = await FuncB();
textBox1.Text += Environment.NewLine + "\nD----" + Thread.CurrentThread.ManagedThreadId;
return t;
}
public async Task<int> FuncB()
{
textBox1.Text += Environment.NewLine + "\nE----" + Thread.CurrentThread.ManagedThreadId;
await Task.Delay(2000);
textBox1.Text += Environment.NewLine + "\nF----" + Thread.CurrentThread.ManagedThreadId;
return 999;
}
private async void Form1_Load(object sender, EventArgs e)
{
textBox1.Text += Environment.NewLine + "\nA----" + Thread.CurrentThread.ManagedThreadId;
var a = await FuncA();
textBox1.Text += Environment.NewLine + "\nB----" + Thread.CurrentThread.ManagedThreadId;
}