轉(zhuǎn)載:https://blog.csdn.net/liuqianggege1/article/details/48135301
1個按鈕,2個textbox,下面這樣可以正確異步,窗體也不會死掉,textBox2會先有結(jié)果,textBox1再有結(jié)果
private async void button1_Click(object sender, EventArgs e)
{
Does();
textBox2.Text = "1";
}
private Task<string> DoWork()
{
return Task.Run( () =>
{
Thread.Sleep(4000);
return "Done with work!";
}
);
}
private async void Does()
{
string text = await DoWork();
textBox1.Text = text;
}
如果把按鈕事件改成下面這樣,窗體不會死,但不會異步執(zhí)行
private async void button1_Click(object sender, EventArgs e)
{
textBox2.Text =await DoWork();
textBox2.Text = "1";
}
順序:
遇到await(在async聲明的方法內(nèi)才可用),當前方法將等待至該await的異步方法返回具體值(int ,string...),同時順序流程返回到調(diào)用方繼續(xù)進行,當前方法仍會進行后續(xù)步驟,相當于從這里創(chuàng)建了新線程。
int a = await getInt();之類的
不想馬上使用異步方法返回值(或在普通方法內(nèi)等待結(jié)果,將阻塞當前線程),只是想讓異步方法開始執(zhí)行,后面才使用結(jié)果:
Task<int> t = getInt();
/*其他需要執(zhí)行的代碼*/
int a = t.Rusult();
如何把普通方法包裝成異步方法:使用Task.Run()
//普通方法
public static void m1(int a, int b) {
//你要干的事情
}
//調(diào)用普通方法的異步方法
public static async Task MethodAnsyc(int a, int b) {
Task t = new Task(() =>
{
try {
AddLBItem(a, b);
}
catch (Exception) {
}
});//匿名函數(shù)作參數(shù)構造Task對象
t.Start();//啟動委托(線程),新線程內(nèi)執(zhí)行上面的匿名函數(shù)
await t;//遇到await,當前線程返回,直到上面的匿名函數(shù)完成后才找時機執(zhí)行后續(xù)代碼
//...后續(xù)代碼
}
}
大體跟java中繼承Thread類差不多。java重寫run方法類似于于這里的Task( () =>{} ),然后調(diào)用Start方法啟動線程。await相等于java中等待線程結(jié)束,有點特殊是在等待結(jié)束的同時還能干別的事。
t.Result()相當于:java中自己添加的用來記錄結(jié)果的類成員(即變量)+死循環(huán)等待線程結(jié)束