wait Task.WhenAll不等待所有任务完成

本文关键字:任务 等待 Task WhenAll wait | 更新日期: 2023-09-27 17:50:56

我最近一直在尝试异步等待,但有些事情仍然无法正常工作。

为什么这个代码不总是导致"100"被写入控制台?

不应该

await Task.WhenAll(tasks); 

等待所有100项任务完成?

static List<int> list = new List<int>();
static void Main(string[] args)
{
    NewMethod();
    Console.ReadLine();
}
private async static void NewMethod()
{
    var tasks = new List<Task>();
    for (int i = 0; i < 100; i++)
    {
        tasks.Add(Func(i));
    }
    Console.WriteLine("Lol");
    await Task.WhenAll(tasks);
    Console.WriteLine(list.Count());
}
static async Task Func(int i)
{
    await Task.Delay(100);
    list.Add(i);
}

我是做错了什么,还是这是某种异步等待的缺点?

也是如此

Task.WaitAll(tasks.ToArray());

一开始我不确定在这种情况下它是否相等。

还有一些类似的问题,但我的例子非常简单,我在现有的答案中找不到解释。

wait Task.WhenAll不等待所有任务完成

遇到元素数量不一致的原因是List<T>不是线程安全的

await Task.Delay(100)之后,将元素添加到列表中的继续操作发生在任意线程池上,并发,因为有多个任务正在执行。如果将实现切换为使用ConcurrentBag<int>,则不会发生这种情况。

在将int添加到列表之前,尝试添加一个锁(列表(。您可能会将多个线程添加到非线程安全列表中。

  • 不要将列表与多线程代码一起使用-在不安全的情况下访问-请使用System.collections.Concurrent中的某个集合
  • 永远不要使用"async void"-在.Net UI应用程序中支持异步单击处理程序是一件可怕的事情(http://haacked.com/archive/2014/11/11/async-void-methods/)

以下代码将适用于您的目的:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ConsoleApplication8
{
    class Program
    {
        static readonly BlockingCollection<int> List = new BlockingCollection<int>();
        static void Main(string[] args)
        {
            var application = NewMethod();
            application.Wait();
            Console.ReadLine();
        }
        private async static Task NewMethod()
        {
            var tasks = new List<Task>();
            for (int i = 0; i < 100; i++)
            {
                tasks.Add(Func(i));
            }
            Console.WriteLine("Lol");
            await Task.WhenAll(tasks);
            Console.WriteLine(List.Sum());
        }
        static async Task Func(int i)
        {
            await Task.Delay(100);
            List.Add(i);
        }
    }
}