I've read Eric lippert's article about async
, and about confusions people had with async
keyword. he said :
it (
async
) means “this method contains control flow that involves awaiting asynchronous operations and will therefore be rewritten by the compiler into continuation passing style to ensure that the asynchronous operations can resume this method at the right spot.” The whole point of async methods it that you stay on the current thread as much as possible
I don't understand this. If I execute an asynchronous method (Task
) and it runs , it surely runs on another thread.
Moreover , If I write a method uses await
, (imho) it releases the normal control flow , and code is refactored alike "ContinueWith
" later , on another thread.
I tested it with (console) :
/*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*/
the result is :
A--7
C--7
D--17 <-----D and B are on different thread
B--17
999
So what did Eric mean by saying "stay on the current thread"?
edit 1:
in asp.net
it also return differnt thread 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
(after getting an answer)
it seems that thread is served only at GUI apps :. I run this code at 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;
}