异步方法的编写与使用

一、异步方法的编写
a) 如果需要使用await,则方法必须用async修饰。控制器、事件处理函数这些都可以使用async,但Main函数却不能。如果需要在Mainh函数中调用异步方法,可以使用Result属性,比如:

HttpClient hc = new HttpClient();
var taskMsg = hc.GetAsync("http://www.bing.com");
var taskRead = taskMsg.Result;

这样写的结果貌似await hc.GetAsync...相同,但await时是释放掉线程,而使用.Result却是让线程暂停(block),可见无法发挥异步的作用,还容易因上下文切换导致死锁。不是很理解,还需要在后续的使用中领悟了。
b)编写异步方法有几种形式,典型的如:

static Task<HttpResponseMessage> Test4Async() {
  HttpClient hc = new HttpClient();
  var taskMsg = hc.GetAsync("http://www.bing.com");
  return taskMsg;
}

返回Task<T>以供后续处理。
对于HttpClient请求,也可以直接返回HttpResponseMessage,需要配合使用async和await

static async Task<HttpResponseMessage> Test4Async() {
  HttpClient hc = new HttpClient();
  var taskMsg =await hc.GetAsync("http://www.rupeng.com");
  return taskMsg;
}

c)另外还有Task.Run/FromResult方法

static Task<int> Test1Async() {
  return Task.Run(() => {
    return 1 + 1;
  });
}


static Task<int> Test2Async() {
  return Task.FromResult(3);
}

Task.Run的参数为Action,看来与thread.Start()来执行被指向的函数是一个原理。

二、异步方法的使用
asp.net中使用async可以提升网站的吞吐量(网站可够应对更高的并发量)。MVC、WebAPI的控制器都是可以用async修饰的,EF提供了异步操作的方法。
a)MVC中可以只需用Task<>包装IActionResult即可

public async Task<IActionResult> Index() {
  using (FileStream stream = System.IO.File.OpenRead("d:/ckcore.txt"))
  using (StreamReader st = new StreamReader(stream)) {
    string txt =  st.ReadToEndAsync();
    return Content(txt);
  }
}


b)EF也为增删改查准备了异步方法,比如SaveChangesAsync、FirstAsync、ForeachAsync等。
c)异步一定要“彻底”,一个标记了async的方法,其整个调用链上的方法都要是异步的。.Result这样的用法会抵消异步带来的好处。


学习资料:如鹏网.net提高班http://www.rupeng.com/News/10/4603.shtml

原文地址:https://www.cnblogs.com/zhixin9001/p/7577519.html