首页 > 解决方案 > Task WaitAll 在 C# 中无法正常工作,用于 DB 任务

问题描述

我在 Northwind DB 上玩了一下异步 LINQ,但遇到了Task.WaitAll(task1, task2). 下面是我从中调用的方法static void Main(string[] args)

public static void PerformDatabaseOperations()
{
    using (var ne = new NORTHWNDEntities())
    {
        try
        {
            var aup = ne.Products.AverageAsync(p => p.UnitPrice)
               .ContinueWith(t => Console.WriteLine($"Average unit price is {t.Result}"));

            var ao = ne.Orders.GroupBy(o => o.OrderDate).AverageAsync(group => (double)group.Count())
                .ContinueWith(t => Console.WriteLine($"Average orders per day is {t.Result}"));

            Task.WaitAll(aup, ao);
        }
        catch (AggregateException ex)
        {
            Console.WriteLine(ex.ToString());
        }       
    }
}

当我运行它时,这会引发 AggregateException:

System.AggregateException: One or more errors occurred. ---> 
System.AggregateException: One or more errors occurred. ---> 
System.NotSupportedException: A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.

这种方法有什么我遗漏的吗?我很感激你的任何暗示。

标签: c#linqasync-await

解决方案


DbContext 不是线程安全的 - 您不能在 2 个线程中使用相同的实例。

按照异常的建议,只需将您的代码更改为:

public static async Task PerformDatabaseOperations()
{
    using (var ne = new NORTHWNDEntities())
    {
        try
        {
            var t = await ne.Products.AverageAsync(p => p.UnitPrice);
            Console.WriteLine($"Average unit price is {t}");

            var ao = await ne.Orders.GroupBy(o => o.OrderDate).AverageAsync(group => (double)group.Count());
            Console.WriteLine($"Average orders per day is {ao}");
        }
        catch (AggregateException ex)
        {
            Console.WriteLine(ex.ToString());
        }       
    }
}

注意async Task方法定义。

如果你真的想同时执行两个查询,每个任务都需要自己的 DbContext 实例。


推荐阅读