关于从异步方法

时间:2015-05-22 18:49:03

标签: c# asp.net .net async-await task-parallel-library

我正熟悉.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绑定操作,而不提及任何异常情况。我确定我错过了一些明显的东西。希望得到一些澄清。

1 个答案:

答案 0 :(得分:6)

  

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

如果您正在进行异步操作时当前线程是空闲的,为什么要使用其他线程?什么会使 线程比你已经使用的线程更好?

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

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

相关问题