【发布时间】:2020-04-29 11:14:37
【问题描述】:
我有这个代码:
var dt = new DeveloperTest();
var tasks = readers.Select(dt.ProcessReaderAsync).ToList();
var printCounterTask = new Task(() => dt.DelayedPrint(output));
printCounterTask.Start();
Task.WhenAll(tasks).ContinueWith(x => dt.Print(output).ContinueWith(_ =>
{
dt.Finished = true;
})).Wait();
printCounterTask.Wait();
这样做是准备将要运行的任务,然后开始(我认为)并行执行,该执行以以下方式开始:
printCounterTask.Start();
这就是延迟打印的作用:
public async Task DelayedPrint(IOutputResult output)
{
while (true)
{
if (!Finished)
{
//every 10 seconds should print.
//at least one print even if the execution is less than 10 seconds
//as this starts in paralel with the processing
Task.Delay(10 * 1000).Wait();
await Print(output);
}
else
{
#if DEBUG
Console.WriteLine("Finished with printing");
#endif
break;
}
}
}
基本上是每 10 秒打印一些延迟的输出,然后当所有任务完成时停止无限循环。 如果你想看完整的代码在这里https://github.com/velchev/Exclaimer-Test
我不确定这是不是
Task.WhenAll(tasks).ContinueWith(x => dt.Print(output).ContinueWith(_ =>
{
dt.Finished = true;
})).Wait();
与 printCounterTask.Start() 并行运行; 当我首次亮相时,它似乎作为 !Finished 代码中的断点被命中,然后也在 else 子句中。据我所知,当您启动一项任务时,它会并行运行,因此所有任务都应该并行运行。任务是线程的表示,与旧语法相比,它在语法上更容易控制。所以所有这些线程都在运行,并且由于更好的语法更容易说 - 等到所有完成然后更改标志。任何有用的解释将不胜感激。谢谢小伙伴们。
【问题讨论】:
-
能否将
ProcessReaderAsync方法的代码包含进来? -
你正在通过
Task.Delay().Wait()阻塞 ThreadPool 中的所有线程。如果所有任务都应该并行运行,请将其更改为await Task.Delay()。 -
@SebastianSchumann
Task.Delay().Wait()是执行一项任务的一部分,printCounterTask。问题中未显示tasks的实现(指向外部站点的链接不计入恕我直言)。 -
@TheodorZoulias 哦 - 是的。错过了。对不起。但 OP 应该改变这一点。
-
如果您使用use
Task.Runinstead ofnew TaskandTask.Start和useawaitinstead ofContinueWith,您的代码将大大简化并且更加清晰。
标签: c# multithreading parallel-processing task