async和await 使得.net写异步方法变得极其容易而且代码可读性极高。
假设需要点击一个按键,所起到的效果是睡10s,然后再进行其他操作(包括UI操作)。 当然可以可以用多线程+托管的方法实现。但是使用async和await之后这个代码会变得很简单,甚至可以用很简单的方法加入超时机制。
1,await 必须在async的方法内。
2,async的方法在await执行的时候,调用async方法的方法不会等待,会继续执行接下来的方法(示例1,2中的messagebox.show()的效果)
3,async的方法如果需要有返回值,那么必须定义成Task<T> 才可以,如果要等待完成返回值,那么又得配合使用上await才可以。
示例1:没有超时的await。代码的执行效果是点击button1的时候,会立马弹框"i am button 1",然后大概10s后label1.text变成0。中途可以拖动UI,进行其他操作。
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "start";
button1click();
MessageBox.Show("i am button 1");
}
private async void button1click()
{
var t = Wait();
int a = await t;
label1.Text = a.ToString();
}
private async Task<int> Wait()
{
return await Task.Run(() =>
{
Thread.Sleep(10000);
return 0;
});
}
private async Task<int> Wait()
{
return await Task.Run(() =>
{
Thread.Sleep(10000);
return 0;
});
}
示例2,加入超时机制。下面代码的执行效果,是立马弹框“i am button2”,然后大概2秒后,label1.text变成-1。 中途可以进行任何UI操作。
private void button2_Click(object sender, EventArgs e)
{
button2click();
MessageBox.Show("i am button 2!");
}
private async Task<int> Wait()
{
return await Task.Run(() =>
{
Thread.Sleep(10000);
return 0;
});
}
private async void button2click()
{
var t = Wait();
int a = await WaitTimeout(t, new TimeSpan(0, 0, 0, 2), -1);
label1.Text = a.ToString();
}
private async Task<TResult> WaitTimeout<TResult>(Task<TResult> task, TimeSpan timeout,TResult timeoutresult)
{
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));
if (completedTask == task)
{
timeoutCancellationTokenSource.Cancel();
return await task;
}
else
{
return timeoutresult;
}
}
}
综上,可以得出一个很简单的结论或者使用效果,使用async和await可以很容易的完成异步操作,而且可以等待完成后继续进行其他操作。