У меня следующий код:
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».
Зачем вам это @PlexisPlexis?
просто хочу, чтобы вы знали, что я дал тот же ответ, что и liam, только что использовал для цикла и предоставил еще один угол для определения задачи





Поскольку тип возвращаемого значения является логическим, вы можете сделать это так, а также прикрепить объект 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 из вопроса?
@ Лиам, да, я пытаюсь показать идею.
Но упускает из виду ...
@AlexRiabov Спасибо за ваш ответ, но, как сказал Лиам, вопрос заключается в утверждениях if.
Что вы можете:
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
а где результат? что такое GetCountForWord? Кажется, вы только что это выдумали?
@Liam, я не думаю, что мне нужно писать точно такой же код. этот код взят с сайта MSDN. это пример кода. «Похоже, вы только что выдумали это». лучше спросите у кого-нибудь из майкрософт :)
Итак, что вы говорите, вы вырезали и вставили это из MSDN? В этом случае вам нужно сделать это как цитату
Этот код не компилируется ... Использование async () => также является пустой тратой времени. Parallel.Invoke предназначен для синхронных задач, а не для асинхронных. async методы уже работают параллельно. Также нет необходимости использовать поток.
да. я вставил я скопировал его из MSDN. Извините. Я думал, что он получит представление о параллельном коде, увидев этот блок кода.
Здесь нет никакой пользы от использования Parallel.ForEach, поскольку задачи уже выполняются параллельно сами по себе. В этом весь смысл асинхронного кода.
@ckuri спасибо ckuri.
Вы пробовали использовать BackgroundWorker? создавая работника для каждой задачи?