加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在调用.WaitAll()C#后,将匿名任务添加到List不会执行它

发布时间:2020-12-15 23:50:39 所属栏目:百科 来源:网络整理
导读:我通过以下方式将任务添加到任务列表中 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(async () =>
    {
        // work here
        await MethodInsideThatNeedsAwaiting(); // if that has anything to do with it
        // more work 
    }));

调用Task.WaitAll(任务列表);之后变得“卡住”.该程序继续运行,但是从该列表中的任何任务都没有听到任何声音,也没有触及任何断点,就像它在某个地方卡在自己的内部异步循环中一样.

我将这个任务添加到列表错误的方式是什么?这是什么问题?

我也尝试过:
我也试过以下,如果由于某种原因async关键字是问题,但它仍然无法正常工作:

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,请调用它以获取任务.
>如果在工作流程可以继续之前需要等待该任务完成,请等待该任务.
>如果您有多个任务,并且需要在工作流程继续之前完成所有任务,请将它们放入集合中,然后调用WhenAll以获取新任务,该任务代表完成所有这些任务的任务.然后你必须等待那个任务.

一些正确的工作流程:

这是最简单的一个:

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
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读