private async void button1_click(object sender, eventargs e) { var length = accesswebasync(); // 这里可以做一些不依赖回复的操作 otherwork(); this.textbox1.text += string.format("\n 回复的字节长度为: {0}.\r\n", await length); this.textbox2.text = thread.currentthread.managedthreadid.tostring(); } private async task<long> accesswebasync() { memorystream content = new memorystream(); // 对msdn发起一个web请求 httpwebrequest webrequest = webrequest.create("http://msdn.microsoft.com/zh-cn/") as httpwebrequest; if (webrequest != null) { // 返回回复结果 using (webresponse response = await webrequest.getresponseasync()) { using (stream responsestream = response.getresponsestream()) { await responsestream.copytoasync(content); } } } this.textbox3.text = thread.currentthread.managedthreadid.tostring(); return content.length; } private void otherwork() { this.textbox1.text += "\r\n等待服务器回复中.................\n"; }
async是同步执行程序,而await起到的则是划分片段以及挂起调用方的作用,并不会创建新的线程,根据大神的分析:
在await关键字出现的前面部分代码和后面部分代码都是同步执行的(即在调用线程上执行的,也就是gui线程,所以不存在跨线程访问控件的问题),await关键处的代码片段是在线程池线程上执行。
在上面的代码中,调用了fcl封装的getresponseasync等方法从而不阻塞当前ui线程,await的确不会创建新的线程,但是就在这里而言,await表达式中的确创建了新的线程——getresponseasync所做的.以至于造成了表面同步的假象。我之前写过一篇文章
c#async与await异步编程学习笔记
await关键字与task有莫大的关联,从其特定的返回值就可以看出来,更深层次的await与task的continuewith函数应该是等效的.因此,用async & await关键字实现异步要么调用fcl封装好的异步方法,要么我们就自己调用task来创建新的线程分担ui线程的任务以防止ui线程阻塞.
以上就是c# 5.0引入了两个关键字 --async和await的详细内容。