转载:https://blog.csdn.net/liuqianggege1/article/details/48135301
1个按钮,2个textbox,下面这样可以正确异步,窗体也不会死掉,textBox2会先有结果,textBox1再有结果
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;
}
如果把按钮事件改成下面这样,窗体不会死,但不会异步执行
private async void button1_Click(object sender, EventArgs e)
{
textBox2.Text =await DoWork();
textBox2.Text = "1";
}
顺序:
遇到await(在async声明的方法内才可用),当前方法将等待至该await的异步方法返回具体值(int ,string...),同时顺序流程返回到调用方继续进行,当前方法仍会进行后续步骤,相当于从这里创建了新线程。
int a = await getInt();
之类的
不想马上使用异步方法返回值(或在普通方法内等待结果,将阻塞当前线程),只是想让异步方法开始执行,后面才使用结果:
Task<int> t = getInt();
/*其他需要执行的代码*/
int a = t.Rusult();
如何把普通方法包装成异步方法:使用Task.Run()
//普通方法
public static void m1(int a, int b) {
//你要干的事情
}
//调用普通方法的异步方法
public static async Task MethodAnsyc(int a, int b) {
Task t = new Task(() =>
{
try {
AddLBItem(a, b);
}
catch (Exception) {
}
});//匿名函数作参数构造Task对象
t.Start();//启动委托(线程),新线程内执行上面的匿名函数
await t;//遇到await,当前线程返回,直到上面的匿名函数完成后才找时机执行后续代码
//...后续代码
}
}
大体跟java中继承Thread类差不多。java重写run方法类似于于这里的Task( () =>{} )
,然后调用Start方法启动线程。await相等于java中等待线程结束,有点特殊是在等待结束的同时还能干别的事。
t.Result()相当于:java中自己添加的用来记录结果的类成员(即变量)+死循环等待线程结束