【问题标题】:How to make use Task.WaitAll with async method using C#如何使用 C# 使用带有异步方法的 Task.WaitAll
【发布时间】:2019-06-17 10:09:56
【问题描述】:

我在HomeControllerasync 方法中使用了Task.WaitAll,但它并没有等待完成async 方法的执行。我在这里做错了什么?它不再等待,而是立即进入下一条语句。

HomeController.cs:

private List<Task> taskList = new List<Task>();

public ActionResult Index()
{
    for (i=0; i<5; i++)
    {
        SendMessages();
    }

    Task.WaitAll(taskList.ToArray());
    // call demo method
}

private async Task SendMessages()
{
    var task = Task.Factory.StartNew(() => ProcessMessages()
    taskList.Add(task);
}

private async Task ProcessMessages()
{
    while (run for 10 minutes)
    {
        // data save
    }
}

我在taskList 中添加了Task,并使用Task.WaitAll(taskList.ToArray()); 等待所有任务完成,然后使用call demo method。但不是等待并执行整个循环,而是在Task.WaitAll(taskList.ToArray()); 之后立即停止并执行call demo method。这是为什么呢?

【问题讨论】:

  • 还有private List&lt;Task&gt; taskList = new List&lt;Task&gt;();一行吗? Index 中定义的当前一个不能被SendMessages 访问以添加任务。所以看起来你正在等待一个空的任务列表。此外,您应该使用await Task.WhenAll 而不是阻塞WaitAll
  • 抱歉 taskList 它在 index() 之外
  • @Neo,你是如何在 ProcessMessages 中实现run for 10 minutes 逻辑的?
  • var startTime = DateTime.UtcNow; while (DateTime.UtcNow - startTime &lt; TimeSpan.FromMinutes(10))
  • @Neo,等待 10 分钟的逻辑不应该是:while((DateTime.UtcNow - startTime).TotalMinutes &lt; 10) 。您提到的代码没有等待 10 分钟,因此您看到 WaitAll 方法不会导致等待 10 分钟。

标签: asp.net-mvc c#-4.0 async-await task task-parallel-library


【解决方案1】:

Task.Factory.StartNew 不应用于启动异步操作,因为它不会解开返回的Task,而是返回一个新的Task,该Task 在异步操作启动后立即完成(或者更准确地说,完成它的同步部分)。你应该改用Task.Run

此外,SendMessages 不应该是异步的。但是,Index 应该是,允许您使用异步的WhenAll 而不是阻塞的WaitAll

private List<Task> taskList = new List<Task>();

public async Task<ActionResult> Index()
{
     for (i = 0; i < 5; i++)
     {
         SendMessages();
     }

     await Task.WhenAll(taskList);
     // call demo method
}

private void SendMessages()
{
    var task = Task.Run(() => ProcessMessagesAsync());   // here
    taskList.Add(task);
}

private async Task ProcessMessagesAsync()
{
    while (run for 10 minutes)
    {
        // data save
    }
}

【讨论】:

  • 好的,我已经让 Index async 和 SendMessages not async 现在...但是为什么不使用 waitall 和 SendMessages not async 呢?请告诉我。非常感谢
  • WaitAll 会阻塞调用线程,直到所有任务都完成,浪费它;而WhenAll 将放弃线程并仅在任务完成后恢复执行。 SendMessages 不需要异步,因为它没有任何等待。
猜你喜欢
  • 2015-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多