c# - 多个 Task.Run 与不等待异步方法?
问题描述
我有一些 IO-Bound 作业(定期将一些数据写入文件)代码如下:
public async Task SaveToFile1(int sleepTimeout)
{
while (true)
{
// Do file saving work
await Task.Delay(sleepTimeout).ConfigureAwait(false);
}
}
public async Task SaveToFile2(int sleepTimeout)
{
while (true)
{
// Do file saving work
await Task.Delay(sleepTimeout).ConfigureAwait(false);
}
}
public async Task SaveToFile3(int sleepTimeout)
{
while (true)
{
// Do file saving work
await Task.Delay(sleepTimeout).ConfigureAwait(false);
}
}
调用者是主要方法。当我使用以下两种方式运行它们时,这些任务运行良好并产生了正确的结果:
void main ()
{
// other codes
// way 1:
SaveToFile1(1000);
SaveToFile2(1000);
SaveToFile3(1000);
// other codes will not let the app exit
}
void main ()
{
// other codes
// way 2:
Task.Run(async() => await SaveToFile1(1000));
Task.Run(async() => await SaveToFile2(1000));
Task.Run(async() => await SaveToFile3(1000));
// other codes will not let the app exit
}
哪种方法是正确的,或者另一种方法是适合我情况的最佳选择?
感谢您的回答!
编辑:
在方式1中,当await Task.Delay
'完成'时,可能会捕获一个新的线程池线程以执行循环的下一步,...,循环将始终在await
命中时在其他线程中运行。
在方式2中,可能会在Task.Run
立即执行时使用新的线程池线程,循环将始终在开始时在其他线程中运行。
结果都一样,区别在哪里?
所以我的问题不在于Task.Run vs async-await!
解决方案
异步代码允许在等待来自其他事物的响应时释放当前线程来做其他工作。但是第一个之前的所有代码await
都将在您调用它的同一线程上完成。如果该代码占用大量 CPU 资源,则可能很明显。
如果您不使用Task.Run
,该方法将在同一个线程上运行,直到第一个异步 I/O 请求,当它返回 aTask
并且您的下一个方法将被调用。
Task.Run
将在不同的线程上执行代码。如果它确实执行了一些 CPU 繁重的工作并且您不希望在当前线程上完成(例如在桌面应用程序中您不希望在 UI 线程上完成),那么这很好。但是启动一个新线程也有一点成本。
使用是否Task.Run
会产生明显的差异取决于您正在编写的应用程序的类型以及您的方法的作用。
如果您不立即等待它们很好,但如果您不等待它们,那么您将永远不知道它们何时完成,是否成功完成,或者抛出异常。这被称为“一劳永逸”。仅当您不在乎他们是否成功时才这样做。
相反,您可以在最后等待以确保它们成功完成。例如:
void main ()
{
// other codes
var taskList = new List<Task>();
taskList.Add(SaveToFile1(1000));
taskList.Add(SaveToFile2(1000));
taskList.Add(SaveToFile3(1000));
// other codes will not let the app exit
// wait till everything finishes before exiting
await Task.WhenAll(taskList);
}
推荐阅读
- c++ - 删除硬编码的 MySQL 连接字符串
- c# - 一键点击链接控制器动作和/或承诺
- angular - 点击事件开启
没有被解雇 - spring - Spring Boot休眠模式验证
- node.js - 如何在 Angular 8 和 NodeJS 12 之间共享代码
- r - 一次制作多个直方图并保存
- visual-studio - 不支持 Xamarin Forms 项目的 Visual Studio 2019 诊断工具?
- elasticsearch - 计算 Elasticsearch 聚合中的非唯一项?
- java - 检查字符串是否包含列表中的任何字符串
- python - 在 Docker 中运行的 Python 代码无法与 NGROK 一起使用