Der*_*tic 3 .net c# asynchronous task
我通过以下方式将任务添加到任务列表中
taskList.Add(new Task(async () =>
{
// work here
await MethodInsideThatNeedsAwaiting(); // if that has anything to do with it
// more work
}));
Run Code Online (Sandbox Code Playgroud)
Task.WaitAll(tasklist);之后的电话会被"卡住".该程序继续运行,但是从该列表中的任何任务都没有听到任何声音,也没有触及任何断点,就像它在某个地方卡在自己的内部异步循环中一样.
我将这个任务添加到列表错误的方式是什么?这是什么问题?
我也尝试了:
我也尝试了以下内容,如果由于某种原因async关键字是问题,但它仍然不起作用:
taskList.Add(new Task(() =>
{
// work here
MethodInsideThatNeedsAwaiting().Wait();
// more work
}));
Run Code Online (Sandbox Code Playgroud)
然而,这可以按预期工作
private async Task GetStuff()
{
// same work here
await MethodInsideThatNeedsAwaiting();
// more work
}
Run Code Online (Sandbox Code Playgroud)
然后使用taskList.Add(GetStuff());Calling 添加它就Task.WaitAll(tasklist);没有问题.
Eri*_*ert 11
你在这里做的一切都是错的.在编写更多异步代码之前,停止正在进行的操作并了解其工作原理.你正在为从未完成的任务做好准备,因为他们从未开始,而且因为他们在等待自己而从未完成的任务.异步工作流程有点棘手.
首先:你几乎不想使用new Task.它只是意味着"创造一个代表这项工作的任务".它并不意味着执行该工作. new Task制作待办事项列表; 它没有做清单上的东西!
其次,你几乎不想使用Task.Run.这意味着创建一个代表工作的任务,并从池中分配一个工作人员来运行它.除非您正在进行的工作是同步的并且受CPU限制,否则您不希望分配工作程序,而您的工作不是.
第三,你几乎从不想在任何已经成为任务的事情上使用它们.你手头有一个异步lambda.它在调用时返回一个任务,因此如果您想要一个正在运行的工作流的任务,请调用lambda!
第四,你几乎从不想WaitAll. 通过将异步工作流程转换回同步工作流程,这破坏了异步的整个过程.
第五,Wait出于同样的原因,你几乎从不想要任务.但它变得更糟!这是我希望你做的待办事项清单:首先,将面包放入烤面包机并开始烘烤.第二,同步等待三明治完成; 在此步骤完成之前不要继续.第三,吃三明治.第四,当烤面包机爆炸时,从烤面包机中取出烤面包,并在烤面包上放一些火腿做三明治. 如果您尝试执行此工作流程,您将永远等待.当您将同步等待插入到它们中时,异步工作流会发生死锁,因为您经常处于等待您将来要做的工作的情况.
(关于最后一点:如果您处于这种情况,正确的解决方案是不要改变工作流程的第二步"雇用一名工人完成我的三明治,并同步等待该工人完成".你.经常看到这种奇怪的,浪费的修复不正确的工作流程. 当您删除同步等待并await在工作流无法继续直到任务完成的点处插入异步等待()时,您会发现您的工作流程可以完成所有工作线程.)
你正在做的每件事都是完成异步编程的错误方法,如果你继续这样做就不会成功.
好的,既然你知道怎么不这样做,你怎么做的?
await该任务.WhenAll以获取新任务,该任务代表完成所有这些任务的任务.那你必须完成await 那项任务.一些正确的工作流程:
这是最简单的一个:
private async Task GetStuffAsync()
{
// same work here
await MethodInsideThatNeedsAwaitingAsync();
// more work
}
private async Task DoItAsync()
{
// do work
await GetStuffAsync();
// do more work
}
Run Code Online (Sandbox Code Playgroud)
如果您有多个任务并且想要等待所有任务,但他们不必等待彼此怎么办?
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
}
Run Code Online (Sandbox Code Playgroud)
如果您有不明数量的此类任务怎么办?
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
}
Run Code Online (Sandbox Code Playgroud)