![](/img/trans.png)
[英]Running multiple tasks in parallel. How to get the reason behind a TaskCancelledException?
[英]Not sure if code runs in parallel. Tasks in console application
我有这个代码:
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秒延迟一次的output,然后当所有任务完成时停止无限循环。 如果你想看整个代码在这里https://github.com/velchev/Exclaimer-Test
我不确定这是否
Task.WhenAll(tasks).ContinueWith(x => dt.Print(output).ContinueWith(_ =>
{
dt.Finished = true;
})).Wait();
与 printCounterTask.Start() 并行运行; 当我首次亮相时,它似乎作为 the.Finished 代码中的断点被击中,然后在 else 子句中也被击中。 据我所知,当您启动一项任务时,它会并行运行,因此所有任务都应该并行运行。 任务是线程的表示,与旧语法相比,它在语法上更容易控制。 所以所有这些线程都在运行,并且由于更好的语法更容易说 - 等到所有线程完成然后更改标志。 任何有用的解释将不胜感激。 谢谢小伙伴们。
编写的代码大部分是正确的,但是Task
构造函数和ContinueWith
周围存在一些细微差别,这使得它难以理解,并且很容易被破解。 例如, printCounterTask.Wait()
不会等到DelayedPrint
完成,因为Task
构造函数不理解异步委托。
为了使代码完全正确并且更易于阅读和推理,请将new Task
/ Start
替换为Task.Run
,并将ContinueWith
替换为await
:
var dt = new DeveloperTest();
var tasks = readers.Select(dt.ProcessReaderAsync).ToList();
var printCounterTask = Task.Run(() => dt.DelayedPrint(output));
await Task.WhenAll(tasks);
await dt.Print(output);
dt.Finished = true;
await printCounterTask;
如果您遵循使用Async
为异步方法添加后缀的约定,您还会发现您的代码更清晰。
任务是线程的表示,与旧语法相比,它在语法上更容易控制。
一点都不。 任务是未来- 表示可能在未来某个时间完成的操作。 这种“操作” 不一定需要线程。 Task.Run
工作排队到线程池,但在此示例中,任务并不总是使用线程池线程(具体来说,它在await Task.Delay
期间不使用线程池线程)。
你说对了一部分。 这些任务将与
打印计数器任务
正如预期的那样。 然而,任务不是线程的表示,也不是更容易控制线程的语法糖化。 在这里您可以找到有用的信息: https://www.dotnetforall.com/difference-task-and-thread/
一般来说,了解任务正在使用线程池中的线程对您来说很重要。
任务是您希望作为后台工作执行的方法的表示(您不想阻塞当前执行),并且任务需要线程才能操作,但任务不是线程.
线程池中的任务可能比可用线程多,这将导致它们在队列中等待可用线程以便执行。
还要考虑 Task.WhenAll 不会为您执行任务,您必须自己执行它们(缺少 ProcessReaderAsync 的实现,但如果您使用的是 Task.Run 就可以了)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.