async await Task
一、使用Task
引用命名空间
using System.Threading.Tasks;
1.工厂方式
Task.Factory.StartNew(() => {Console.WriteLine("Hello Task library!"); });
2.实例方式
Task task = new Task(() => PrintMessage()); task.Start();
3. .NET4.5
Task.Run(() => PrintMessage());
//将指定的结果包装为已完成的TaskTask.FromResult<
int
>(GetSum(4, 5));
二、async和await
async和await
(1)在async标识的方法体里面,如果没有await关键字的出现,那么这种方法和调用普通的方法没什么区别。
(2)在async标识的方法体里面,在await关键字出现之前,还是主线程顺序调用的,直到await关键字的出现才会出现线程阻塞。
(3)await关键字可以理解为等待方法执行完毕,除了可以标记有async关键字的方法外,还能标记Task对象,表示等待该线程执行完毕。所以await关键字并不是针对于async的方法,而是针对async方法所返回给我们的Task。
(4)asyc方法的返回类型必须为void、Task或者Task<T>类型。也就是说async要么是void,要么和Task关联。
三、注意事项
在Asp.net中,一旦在代码中使用了异步,最好一直使用。调用异步方法时,应该用await等待它返回的task对象。一定要避免使用Task.Wait或Task<T>.Result方法,因为这两个方法会阻塞线程。
public ActionResult DeadLock() { Task task = WaitAsync(); //同步程序块,正在等待异步方法完成 task.Wait(); return Content("执行完毕"); } async Task WaitAsync() { await Task.Delay(TimeSpan.FromSeconds(5)); }
DeadLock()方法先调用了一个异步方法,然后因为使用了task.Wait()阻塞了线程,所以在异步方法体内,当Task.Delay执行完成时,await 无法获取到关联上下文线程,就会一直等待,要解决这个问题可以在WaitAsync中使用ConfigureAwait(false),这样await便可以忽略上下文的关联线程,另一种方法是将DeadLock