我在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.
这种方法有什么我想念的吗?感谢您的提示。
答案 0 :(得分:5)
DbContext is not thread safe - you cannot use the same instance in 2 threads.
Following advice from the exception, just change your code to:
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());
}
}
}
Notice async Task
in method definition.
If you really want to perform two queries at the same time, each task needs its own DbContext instance.