这正是我们想要使用 async-await 的场景!
当您的线程必须空闲等待其他事情完成时,异步等待很有用。例如,要读取的文件、要执行的数据库查询、要下载的网页。通常情况下,其他人正在做工作,而您的线程只是在等待工作完成。
您可以“做其他事情而不是无所事事地等待”的功能被声明为异步。读取文件时见Stream.ReadAsync,执行数据库查询时见Dapper.SQLMapper.QueryAsync,实体框架中的数据库查询见ToListAsync 和FirstOrDefaultAsync,互联网下载等见WebClient.DownloadFileAsync。
如果您调用异步函数,则返回值为Task 而不是void,或者是Task<TResult> 而不是TResult。有一个例外:事件处理程序不会产生任务,而是无效。
如果您想从 async-await 中受益,您必须定义您的函数 async 并返回 Task 或 Task<TResult>
当您调用异步函数时,您可能会确定该函数中的某处是等待。事实上,如果您忘记在某个地方等待,您的编译器会警告您。同样,如果您定义函数 async 但忘记调用另一个异步函数,则会收到警告
调用其他异步函数后,只要不需要调用结果,就可以继续工作。只要您需要结果,您就可以等待任务。
如果您开始等待任务,但数据仍然不可用,那么您的线程将向上调用其调用堆栈,以查看您的调用者是否有事要做,直到您的调用者等待。再次向上调用堆栈,看看是否有工作要做等。
async Task<MyResult> GetMyData(...)
{
Task<SomeData> taskGetData = GetDataFromCloud(...);
// while the data is being fetched, we can continue working
DoSomethingElse();
// now we need the data:
SomeData fetchedData = await taskGetData;
MyResult result = ProcessFetchedData(fetchedData);
return result;
}
帮助我理解 async-await 的是 this interview with Eric Lippert。在中间某处搜索 async-await。
this article by the ever so helpful Stephen Cleary也帮助了我