关于从异步方法同步调用 CPU 绑定方法的困惑

Confusion about calling CPU-bound methods synchronously from an async method

我对 .NET 4.5 的 async/await 结构很感兴趣。我正在研究 RESTful Web API 解决方案。我正在尝试弄清楚如何处理 CPU 绑定操作 - 1) 从当前线程同步调用它,或 2) 使用 Task.Run()?

让我们使用这个page中的例子:

async Task<int> AccessTheWebAsync()
{ 
    // You need to add a reference to System.Net.Http to declare client.
    HttpClient client = new HttpClient();

    // GetStringAsync returns a Task<string>. That means that when you await the 
    // task you'll get a string (urlContents).
    Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

    // You can do work here that doesn't rely on the string from GetStringAsync.
    DoCPUBoundWork();

    // The await operator suspends AccessTheWebAsync. 
    //  - AccessTheWebAsync can't continue until getStringTask is complete. 
    //  - Meanwhile, control returns to the caller of AccessTheWebAsync. 
    //  - Control resumes here when getStringTask is complete.  
    //  - The await operator then retrieves the string result from getStringTask. 
    string urlContents = await getStringTask;

    // The return statement specifies an integer result. 
    // Any methods that are awaiting AccessTheWebAsync retrieve the length value. 
    return urlContents.Length;
}

在这里,我们假设 DoCPUBoundWork() 是严格 CPU 绑定的并且不涉及任何类型的 IO。

如图所示,从当前线程调用它是最佳做法吗?

还是有以下的比较好?

await Task.Run(() => DoCPUBoundWork()).ConfigureAwait(false);

我已经阅读了 Cleary 先生的一些帖子,并且得到了一些混合的建议。在此 post, he suggests that it's better to call the CPU-bound stuff synchronously to avoid the unnecessary overhead of async/await/Task.Run(). However, in this post 中,他建议将 Task.Run() 用于 CPU 绑定操作,但未提及任何异常情况。我确定我遗漏了一些明显的东西。希望得到一些澄清。

Is it the best practice to call it from the current thread as shown?

如果异步操作正在进行时您当前的线程是空闲的,为什么要使用不同的线程?是什么让 那个 线程比您已经在使用的线程更好?

关于 DoIndependentWork 实际上在做什么的问题浮现在脑海中。如果它在 HTTP 请求完成之前完成很重要,我会同步调用它。如果在 HTTP 请求完成之前完成工作不是很重要,那么我会寻找一个完全不同的解决方案。在 ASP.NET.

中使用 Task.Run 是危险的

请记住 ASP.NET 运行 中任意线程池线程的延续。