Tôi đã đọc số article của Eric lippert về async
và về những nhầm lẫn mà mọi người có với từ khóa async
. ông nói:không đồng bộ - hãy ở lại luồng hiện tại?
nó (
async
) có nghĩa là “phương pháp này chứa dòng điều khiển mà liên quan đến việc chờ hoạt động không đồng bộ và do đó sẽ được viết lại bởi trình biên dịch vào tiếp tục đi qua phong cách để đảm bảo rằng hoạt động không đồng bộ có thể tiếp tục phương pháp này ở đúng chỗ.”toàn bộ vấn đề của phương pháp async nó mà bạn ở lại trên thread hiện hành càng nhiều càng tốt
tôi không hiểu điều này. Nếu tôi thực hiện một phương thức không đồng bộ (Task
) và nó chạy, nó chắc chắn chạy trên một chuỗi khác.
Hơn nữa, Nếu tôi viết một phương pháp sử dụng await
, (IMHO) nó giải phóng các dòng điều khiển bình thường, và đang refactored như nhau "ContinueWith
" sau đó, vào khác chủ đề.
Tôi đã thử nghiệm nó với (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*/
kết quả là:
A--7
C--7
D--17 <-----D and B are on different thread
B--17
999
Vậy điều gì đã Eric nghĩa bằng cách nói "ở trên thread hiện tại"?
chỉnh sửa 1:
trong asp.net
nó cũng trở 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
chỉnh sửa 2
(sau khi nhận được một câu trả lời)
có vẻ như chủ đề đó được phục vụ chỉ ở các ứng dụng GUI:. Tôi chạy mã này ở 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;
}
Liên kết tới bài viết bạn đang nhầm lẫn về –
@downvoter - nhận xét sẽ hữu ích. –
Tác vụ bạn đang chờ chạy trên một chuỗi khác. Tất cả các mã khác trong phương thức async chạy trên luồng ban đầu. Chờ đợi không bắt đầu một nhiệm vụ mới. Nó tương đương với một ContinueWith trong chuỗi ORIGINAL. Có nhiều blog thảo luận về điều này. –