在调用.WaitAll()C#后,将匿名任务添加到List不会执行它
|
我通过以下方式将任务添加到任务列表中
taskList.Add(new Task(async () =>
{
// work here
await MethodInsideThatNeedsAwaiting(); // if that has anything to do with it
// more work
}));
调用Task.WaitAll(任务列表);之后变得“卡住”.该程序继续运行,但是从该列表中的任何任务都没有听到任何声音,也没有触及任何断点,就像它在某个地方卡在自己的内部异步循环中一样. 我将这个任务添加到列表错误的方式是什么?这是什么问题? 我也尝试过: taskList.Add(new Task(() =>
{
// work here
MethodInsideThatNeedsAwaiting().Wait();
// more work
}));
然而,这可以按预期工作 private async Task GetStuff()
{
// same work here
await MethodInsideThatNeedsAwaiting();
// more work
}
然后用taskList.Add(GetStuff())添加它;调用Task.WaitAll(任务列表);这个问题没有问题. 解决方法
你在这里做的一切都是错的.在编写更多异步代码之前,停止正在进行的操作并了解其工作原理.你正在为从未完成的任务做好准备,因为他们从未开始,而且因为他们在等待自己而从未完成的任务.异步工作流程有点棘手.
首先:你几乎不想使用新任务.它只是意味着“创造一个代表这项工作的任务”.它并不意味着执行该工作.新任务制定待办事项列表;它没有做清单上的东西! 其次,你几乎不想使用Task.Run.这意味着创建一个代表工作的任务,并从池中分配一个工作人员来运行它.除非您正在进行的工作是同步的并且受CPU限制,否则您不希望分配工作程序,而您的工作不是. 第三,你几乎从不想在任何已经成为任务的事情上使用它们.你手头有一个异步lambda.它在调用时返回一个任务,因此如果您想要一个正在运行的工作流的任务,请调用lambda! 第四,你几乎从不想等待.通过将异步工作流程转换回同步工作流程,这破坏了异步的全部要点. 第五,出于同样的原因,你几乎不想在任务上调用Wait.但它变得更糟!这是我希望你做的待办事项清单:首先,将面包放入烤面包机并开始烘烤.第二,同步等待三明治完成;在此步骤完成之前不要继续.第三,吃三明治.第四,当烤面包机爆炸时,从烤面包机中取出烤面包,并在烤面包上放一些火腿做三明治.如果您尝试执行此工作流程,您将永远等待.当您将同步等待插入到它们中时,异步工作流会发生死锁,因为您经常处于等待您将来要做的工作的情况. (关于最后一点:如果您处于这种情况,正确的解决方案是不要改变工作流程的第二步“雇用一名工人完成我的三明治,并同步等待该工人完成”.你.经常看到这种奇怪的,浪费的修复工作不正确的工作流程.当您删除同步等待并插入异步等待(等待)工作流无法继续直到任务完成时,您会发现您的工作流可以完成所有工作一个帖子.) 你正在做的每件事都是完成异步编程的错误方法,如果你继续这样做就不会成功. 好的,既然你知道怎么不这样做,你怎么做的? >如果您有返回任务的方法或lambda,请调用它以获取任务. 一些正确的工作流程: 这是最简单的一个: private async Task GetStuffAsync()
{
// same work here
await MethodInsideThatNeedsAwaitingAsync();
// more work
}
private async Task DoItAsync()
{
// do work
await GetStuffAsync();
// do more work
}
如果您有多个任务并且想要等待所有任务,但他们不必等待彼此怎么办? private async Task DoItAsync()
{
// do work
Task t1 = GetStuffAsync();
// do work
Task t2 = GetOtherStuffAsync();
// do more work
// We cannot continue until both are done
await t1;
await t2;
// do even more work
}
如果您有不明数量的此类任务怎么办? private async Task DoItAsync()
{
// do work
var tasks = new List<Task>();
while (whatever)
tasks.Add(GetStuffAsync());
// do work
// we cannot continue until all tasks are done
await Task.WhenAll(tasks);
// do more work
}
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
