当我调用 foo() 时,此方法是否在单独的线程上运行?
public async Task<bool> foo(){
//Some code
}
不,不是的。它可以在内部启动另一个线程并返回该任务,但总体思路是它不在任何线程上运行。
让我解释。async 的一般用途是如果您不受 CPU 限制,这意味着 IO 和 windows 中的所有 IO 在最低级别都有回调操作接口,所以 - 网络请求发送请求然后继续工作 - 但没有线程随附的。完全没有。async 的一般用例是 async 在线程上运行,当无事可做时,它将使用线程完成任务,允许在一个线程上进行多个操作 - 并且...... IO 不会用完线程.
您的方法基本上变成了状态引擎,将控制权交给任务调度程序,等待发出已完成任务的信号。
制作方法async并不意味着它会创建另一个线程。如果CLR看到在您的方法中调用await的async方法被延迟,则它将退出该方法并在等待的方法完成后等待,然后使用另一个线程继续该方法。
当您调用标记为 的方法时async,它开始在当前线程上同步运行。
因此,结论是async不会创建它自己的thread. 调用方法的线程用于执行该async方法,直到找到一个awaitable。然后,同一线程继续执行async方法调用之外的其余调用方法。在被调用的方法中,从等待返回后,可以在线程池中async的一个线程上执行延续,这是唯一一个单独的线程出现的地方。
不,这些任务并不意味着有一个单独的线程在运行。如果您的任务需要在其方法体中阻塞另一个异步任务,它可以在等待阻塞的资源时暂时返回执行,然后返回执行以完成任务。这基本上就是await关键字的用途。典型的异步任务是在真正的异步操作开始后等待 I/O 或网络资源返回数据的任务。您的方法本身也可能产生自己的线程,使其异步,但它实际上仅取决于异步方法本身的实现。
在此页面上的“烹饪早餐类比”中找到了一个很好的解释: https ://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
请注意,可以并行运行任务,这可以产生单独的线程,但是当您直接调用方法时,默认情况下不会这样做。