我正熟悉.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中,他建议同步调用CPU绑定的东西以避免async/await/Task.Run()
的不必要开销。但是,在这个post中,他建议使用Task.Run()
进行CPU绑定操作,而不提及任何异常情况。我确定我错过了一些明显的东西。希望得到一些澄清。
答案 0 :(得分:6)
如图所示,从当前线程调用它是最佳做法吗?
如果您正在进行异步操作时当前线程是空闲的,为什么要使用其他线程?什么会使 线程比你已经使用的线程更好?
关于DoIndependentWork
实际正在做什么的问题浮现在脑海中。如果在HTTP请求完成之前完成它是至关重要的,我会同步调用它。如果在HTTP请求完成之前完成工作并不重要,那么我会寻找完全不同的解决方案。在ASP.NET中使用Task.Run
是危险的。
请记住,ASP.NET中的延续在任意线程池线程上运行。