Параллельное выполнение задач в C#

У меня следующий код:

if (AObjList.Count > 0)
{
  var ARes = await insertA(AObjList);
  if (!ARes) return false;
}

if (BObjList.Count > 0)
{
  var BRes = await insertB(BObjList);
  if (!BRes) return false;
}

return true;

Я хотел бы запустить две асинхронные функции (insertA () и insertB) параллельно, но если я это сделаю

List<Task> tasks = new List<Task>();
if (AObjList.Count > 0)
{
  tasks.Add(insertA(AObjList));
}

if (BObjList.Count > 0)
{
  tasks.Add(insertB(BObjList));
} 

await Task.WhenAll(tasks);

Не могу получить результаты задач, чтобы их проверить.

Есть хороший способ сделать это?

Спасибо!

Обновлено: вопрос был помечен как дублированный, но для меня это не потому, что в этом случае вы можете запустить функцию async или нет. Так что я не могу:

 if (AObjList.Count > 0)
{
  var ATask = insertA(AObjList);
}

if (BObjList.Count > 0)
{
  var BTask = insertB(BObjList);
}

var ARes = await ATask; // ERROR
var BRes = await BTask  // ERROR

return true;

Потому что переменные ATask и BTask находятся внутри области условия «if».

Вы пробовали использовать BackgroundWorker? создавая работника для каждой задачи?

Plexis Plexis 19.06.2018 11:51

Зачем вам это @PlexisPlexis?

Liam 19.06.2018 11:51

просто хочу, чтобы вы знали, что я дал тот же ответ, что и liam, только что использовал для цикла и предоставил еще один угол для определения задачи

Pranay Rana 20.06.2018 06:32
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
193
5

Ответы 5

Поскольку тип возвращаемого значения является логическим, вы можете сделать это так, а также прикрепить объект AsyncState с задачей для идентификации задачи.

Подробности читайте здесь: TPL: определить и найти задачу

List<Task<bool>> tasks = new List<Task<bool>>();
//rest of the code 
if (AObjList.Count > 0)
{
  //"Task A" state object to idetify its task A
  tasks.Add(Task.Factory.StartNew(()=> insertA(AObjList), "Task A"));
}

if (BObjList.Count > 0)
{
  //"Task B" state object to idetify its task B
  tasks.Add(Task.Factory.StartNew(() => insertB(BObjList), "Task B"));
} 
await Task.WhenAll(tasks);
foreach(var t in tasks)
{
  Console.WriteLine(t.AsyncState.ToString());
  Console.WriteLine(t.Result);
}

Вы можете назначить каждую задачу отдельной переменной, а затем использовать их для получения значения, например:

var taskA = insertA(AObjList);
var taskB = insertB(BObjList);

var tasks = new List<Task>{taskA, taskB};

await Task.WhenAll(tasks);

var resultA = await taskA;
var resultB = await taskB;

Вы удалили операторы if из вопроса?

Liam 19.06.2018 12:04

@ Лиам, да, я пытаюсь показать идею.

Alex Riabov 19.06.2018 12:16

Но упускает из виду ...

Liam 19.06.2018 12:17

@AlexRiabov Спасибо за ваш ответ, но, как сказал Лиам, вопрос заключается в утверждениях if.

Kane 20.06.2018 03:29

Что вы можете:

List<Task> tasks = new List<Task>();
if (AObjList.Count > 0)
{
  tasks.Add(insertA(AObjList));
}

if (BObjList.Count > 0)
{
  tasks.Add(insertB(BObjList));
} 

await Task.WhenAll(tasks);

if (tasks.Any(t => !t.Result))
{
  return false;
}

Предполагая, что ваш Task возвращает bool, и вы хотите вернуть false, если какой-либо из них возвращает false, вы можете сделать это следующим образом:

//need to specify the return type here
List<Task<bool>> tasks = new List<Task<bool>>();
if (AObjList.Count > 0)
{
  tasks.Add(insertA(AObjList));
}

if (BObjList.Count > 0)
{
  tasks.Add(insertB(BObjList));
} 

//await the result as usual
await Task.WhenAll(tasks);

//you can only use Result here because you've awaited. Never use this without await 
//as this can cause deadlocks
return tasks.All(a => a.Result);

вы можете использовать параллельную задачу.

bool aResult;
bool bResult;   

     Parallel.Invoke(() =>
                                     {
                                        if (AObjList.Count > 0)
    {
       aResult = await insertA(AObjList);

    }
                                     },  // close first Action

                                     () =>
                                     {
                                         if (BObjList.Count > 0)
    {
       bResult = await insertB(BObjList);

    }
                                     }
                                 ); //close parallel.invoke

подробнее см. https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-use-parallel-invoke-to-execute-parallel-operations

а где результат? что такое GetCountForWord? Кажется, вы только что это выдумали?

Liam 19.06.2018 12:02

@Liam, я не думаю, что мне нужно писать точно такой же код. этот код взят с сайта MSDN. это пример кода. «Похоже, вы только что выдумали это». лучше спросите у кого-нибудь из майкрософт :)

anoop 19.06.2018 12:07

Итак, что вы говорите, вы вырезали и вставили это из MSDN? В этом случае вам нужно сделать это как цитату

Liam 19.06.2018 12:10

Этот код не компилируется ... Использование async () => также является пустой тратой времени. Parallel.Invoke предназначен для синхронных задач, а не для асинхронных. async методы уже работают параллельно. Также нет необходимости использовать поток.

Liam 19.06.2018 12:13

да. я вставил я скопировал его из MSDN. Извините. Я думал, что он получит представление о параллельном коде, увидев этот блок кода.

anoop 19.06.2018 12:14

Здесь нет никакой пользы от использования Parallel.ForEach, поскольку задачи уже выполняются параллельно сами по себе. В этом весь смысл асинхронного кода.

ckuri 19.06.2018 12:39

@ckuri спасибо ckuri.

anoop 19.06.2018 15:59

Другие вопросы по теме