Задача WaitAll не работает должным образом в C # для задачи БД - PullRequest
0 голосов
/ 05 апреля 2019

Я немного поиграюсь с асинхронным LINQ на Northwind DB, но столкнулся с проблемой с 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.

Что-то мне не хватает в этом подходе? Я ценю любой твой намек.

1 Ответ

5 голосов
/ 05 апреля 2019

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...