В вашем примере вы, кажется, запускаете два продолжения параллельно, поэтому существует вероятность, что они будут перекрываться, вызывая проблему параллелизма. DbContext
не является потокобезопасным, поэтому вам необходимо убедиться, что ваши асинхронные вызовы являются последовательными. Имейте в виду, что использование async
/ await
просто превратит ваш код в конечный автомат, чтобы вы могли контролировать, какие операции завершены, прежде чем переходить к следующей операции. Использование одних только асинхронных c методов не обеспечит параллельные операции, а завершение вашей операции в Task.Run
. Поэтому вам нужно спросить себя, действительно ли Task.Run
действительно требуется (т. Е. Планирование работы в ThreadPool), чтобы сделать его параллельным.
Вы упомянули, что в вашем реальном коде у вас есть 3 родительские задачи, и у каждого из них есть 1-5 связанных задач прилагается к ним. Если у 3 родительских задач есть отдельные DbContexts, они могут выполняться параллельно (каждая из них заключена в Task.Run
), но их цепочечные продолжения должны быть последовательными (используя ключевые слова async / await). Например:
public async Task DoWork()
{
var parentTask1 = Task.Run(ParentTask1);
var parentTask2 = Task.Run(ParentTask2);
var parentTask3 = Task.Run(ParentTask3);
await Task.WhenAll(parentTask1 , parentTask2, parentTask3);
}
private async Task ParentTask1()
{
// chained child asynchronous continuations
await Task.Delay(100);
await Task.Delay(100);
}
private async Task ParentTask2()
{
// chained child asynchronous continuations
await Task.Delay(100);
await Task.Delay(100);
}
private async Task ParentTask3()
{
// chained child asynchronous continuations
await Task.Delay(100);
await Task.Delay(100);
}
Если ваши родительские задачи работают с одним и тем же DbContext, во избежание параллелизма вам нужно будет ожидать их один за другим (не нужно заключать их в Task.Run
):
public async Task DoWork()
{
await ParentTask1();
await ParentTask2();
await ParentTask3();
}