【发布时间】:2019-11-28 03:29:56
【问题描述】:
我有一些 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 与 async-await!
【问题讨论】:
-
正确的方法 non
-
那是“I/O 代码”?对我来说好像睡了很多觉
-
@Selvin 请添加 Console.ReadKey();在 main 的最后,我在真实环境中有一些块代码。由于 dotnetfiddle 不支持循环代码,因此您应该使用真正的控制台应用程序。
-
@MickyD 在下次睡眠之前有一些 IO 代码。
-
“结果是一样的,区别在哪里?” -- 你自己已经发现了区别:使用
Task.Run()会导致你的@ 初始执行987654329@ 方法发生在线程池线程而不是当前线程中。这可能很重要,也可能不重要,具体取决于初始代码需要多长时间。标记的重复项也有解释这种确切差异的答案。它是唯一的材料,IMO。如果不是这样,我会说永远不要将Task.Run()与异步方法一起使用。许多(如果不是大多数)异步方法旨在尽快到达第一个等待。
标签: c# asynchronous task