【发布时间】:2020-03-27 12:58:02
【问题描述】:
我仍然无法理解异步/等待。我试图弄清楚是否需要将 CPU 密集型工作负载包装在下面的 Task.Run 中。有人能告诉我哪种方法更好吗?
没有Task.Run:
public async Task ProcessData()
{
//Get some data
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("myUrl");
string data = await response.Content.ReadAsStringAsync();
//Calculate result
string result = null;
for (int i = 0; i < 10000000; i++)
{
//Do some CPU intensive work
}
//Save results
using (var fs = new FileStream("myFile.txt", FileMode.Create))
using (var writer = new StreamWriter(fs))
{
await writer.WriteLineAsync(result);
}
}
使用 Task.Run:
public async Task ProcessData()
{
//Get some data
var httpClient = new HttpClient();
var response = await httpClient.GetAsync("myUrl");
string data = await response.Content.ReadAsStringAsync();
//Calculate result
string result = null;
await Task.Run(() =>
{
for (int i = 0; i < 10000000; i++)
{
//Do some CPU intensive work
}
});
//Save results
using (var fs = new FileStream("myFile.txt", FileMode.Create))
using (var writer = new StreamWriter(fs))
{
await writer.WriteLineAsync(result);
}
}
我的直觉是不使用 Task.Run,但在这种情况下,这是否意味着异步方法中的所有代码都将在单独的线程上执行?意味着调用线程直到最后才会被中断(文件流关闭并且方法结束)?
或者调用者线程是否会被中断并返回此方法以首先执行 CPU 密集型部分,然后在 ProcessData() 为 FileStream 部分在后台运行时返回它正在执行的任何操作?
我希望这很清楚。
提前致谢
【问题讨论】:
-
使用
Parallel.Foreach()进行多线程 CPU 绑定工作。Parallel.Foreach(Enumerable.Range(0, 10000000), i => //Do some CPU intensive work); -
我看不出有一个任务运行 cpu 工作与你等待它之后没有它有什么区别。另一方面,如果你想加快这部分的速度,你可以并行化它,但你不会为此使用 async/await 和任务。
-
您打算从 Windows 窗体或 WPF 应用程序的事件处理程序中调用
ProcessData方法吗?还是会从 ASP.NET 应用程序内部调用?顺便说一句,根据guidelines,异步方法应该有后缀Async。所以ProcessData方法应该命名为ProcessDataAsync。 -
此代码只是一个示例。我不能使用 parallel.foreach 因为 CPU 绑定的工作实际上是一个外部库调用。就上下文而言,这是一个 Windows 服务应用程序。
标签: c# async-await