在调用.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 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |