await 作用于 Task或者返回Task的方法,无论其有没有async修饰。
注意:如果没有使用await仅仅调用标识了async的方法,内部不会执行,只是返回一个Task
如果该方法为void,内部会执行。
//////////////////////////////////////////////////////
〇。简单使用实例。
private async void button1_Click(object sender, EventArgs e) { try { this.label1.Text= await JustDO2();//或者await JustDO(); } catch (Exception ex) { this.label1.Text=ex.Message; } } private async Task<string> JustDO() { await Task.Delay(2000); //throw new Exception("ooops"); return "OK"; } private Task<string> JustDO2() { return Task.Run(() => { Task.Delay(TimeSpan.FromSeconds(4)).Wait(); throw new Exception("oooops"); return Task.FromResult("OK"); }); }
一。使用并发的泛型方法
static async Task<T> DelayResult<T>(T result,TimeSpan delay) { await Task.Delay(delay); return result; }
如何调用,点击按钮,更新文本。
private async void button1_Click(object sender, EventArgs e) { this.label1.Text = await DelayResult<string>("OK", TimeSpan.FromSeconds(5)); }
二。指数退避使用HttpClient访问
static async Task<string> DownloadStringWithRetries(string uri) { using (var client =new HttpClient()) { var nextDelay = TimeSpan.FromSeconds(1); for(int i=0;i!=3;++i) { try { return await client.GetStringAsync(uri); } catch (Exception) { } await Task.Delay(nextDelay); nextDelay = nextDelay +nextDelay; } return await client.GetStringAsync(uri); } }
另外一种超时机制使用Task.WhenAny
private async Task<string> DownloadStringWithTimeout(string uri) { using(var client=new HttpClient()) { var downloadTask = client.GetStringAsync(uri); var timeoutTask = Task.Delay(2000); var completedTask = await Task.WhenAny(downloadTask, timeoutTask); if (completedTask == timeoutTask) return null; return await downloadTask; } }
三。取消
//Form上2个按钮,点击start启动线程,点击cancel取消线程 private async void start_Click(object sender, EventArgs e) { start.Enabled = false; cancel.Enabled = true; try { cts = new CancellationTokenSource(); var token = cts.Token; await Task.Run(() => { for (int i = 1; i <= 100; i++) { dispatcher.Invoke(() => { label1.Text = i + "%"; }); Task.Delay(100).Wait(); token.ThrowIfCancellationRequested(); } } , token ); MessageBox.Show(" task Done."); } catch(OperationCanceledException ) { MessageBox.Show(" Task Canceled."); } catch (Exception ex) { MessageBox.Show("task DONE with errors"); }finally{ start.Enabled=true; cancel.Enabled=false; } } private void cancel_Click(object sender, EventArgs e) { cts.Cancel(); }
超时取消
4秒取消 方式1: cts.CancelAfter(4000); 方式2: cts = new CancellationTokenSource(4000);