首先,你应该知道,仅仅因为你使用await
关键字异步调用了一个方法,并不意味着该方法不能同步运行。或者更准确地说:此类方法通常返回 aTask
或Task<T>
an IAsyncOperation<TResult>
(在 Windows 运行时中),并且该任务很可能在方法返回时完成。在这种情况下,开销非常小,因为正在执行的线程将继续运行。
至于阈值本身,这取决于您要做什么以及在哪个环境中运行。这是 UI 应用程序还是服务器应用程序?您是要异步运行以释放 UI,还是要更好(即更具可扩展性)使用服务器线程?
对于 Windows 运行时 API,Microsoft 使用了 50 毫秒的阈值,这意味着任何可能需要超过 50 毫秒才能执行的方法仅以异步形式提供。这背后的逻辑相当简单:这样做可以让 UI 线程执行长过程,并且永远不会被阻塞超过 50 毫秒。换句话说,UI 线程可以运行其他有用的代码,例如每秒渲染一帧 20 次或更多。
Charles Petzold在他的博客上写了一篇很好的文章。
对于服务器场景,只要通过释放线程可以完成的工作超过释放线程所需的工作,异步运行就变得很有用。根据我的经验,几乎所有 IO 都是这种情况。当然,看起来像 IO,但实际上是从内存缓冲区读取或写入,但在这些情况下,方法返回的任务将同步完成。