Асинхронная задача, ожидающая другую задачу - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть такой код:

private async Task<bool> DoAsyncThing()
{
  await doOtherThings();
} 

private async Task<bool> DoAsyncThing2()
{
  await doOtherThings2();
} 

private async Task<bool> SaveAll()
{
   return await _context.SaveChangesAsync() > 0;
}

public async Task<bool> FirstBatchProcess()
{
    var tasks = new List<Task<bool>>();
    ...
    users.Foreach(user => {
        task.Add(this.DoAsyncThing());
    });
    await Task.WhenAll(tasks);
    return await this.SaveAll();
}

public async Task<bool> SecondBatchProcess()
{
    // get all data from batch 1 and then do calculation
    var tasks = new List<Task<bool>>();
    ...
    users.Foreach(user => {
        task.Add(this.DoAsyncThing2());
    });
    await Task.WhenAll(tasks);
    return await this.SaveAll();
}


public async Task<bool> ProcessAll()
{
    await this.FirstBatchProcess();
    await this.SecondBatchProcess();
}

В ProcessAll я хочу, чтобы firstBatchProcess выполнялся первым, а затем SecondBatchProcess.Потому что у меня есть некоторые данные из FirstBatchPRocess для последующего использования в SecondBatchProcess.Если я запускаю этот код, оба будут выполняться асинхронно и вызывать ошибку, потому что SecondBatchProcess требовал данных, сгенерированных из FirstBatchProcess.

примечание: оба BatchProcess содержат несколько асинхронных циклов, поэтому я использую Task.WhenAll () Как ждать FirstBatchProcessзакончил, затем выполнил SecondBatchProcess?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Обновление

, поэтому, когда я вызываю Task.Wait (), он будет ждать выполнения этой задачи, затем продолжит другой процесс?

Поскольку вы отредактировали свой вопрос, и если я вас правильно понял (я читаю между строк)

await this.FirstBatchProcess();  // will wait for this to finish
await this.SecondBatchProcess(); // will wait for this to finish

Ответ - да, все задачи, запущенные в FirstBatchProcess, будут выполнены до того, как он будет выполнен SecondBatchProcess

Оригинал

Task.WhenAll Method

Создает задачу, которая будет завершена, когда всеиз поставленных заданий выполнено .

Я думаю, вы, возможно, путаетесь с оператором await

await (C # Reference)

Оператор ожидания применяется к задаче в асинхронном методе для вставки точки приостановки при выполнении метода до тех пор, пока ожидаемое задание не завершится .Задача представляет собой текущую работу.

Она действительно ждет!

Ваша полная демонстрация здесь

private static async Task DoAsyncThing()
{
    Console.WriteLine("waiting");
    await Task.Delay(1000);
    Console.WriteLine("waited");
}

private static async Task SaveAll()
{
    Console.WriteLine("Saving");
    await Task.Delay(1000);
}

public static async Task ProcessAll()
{
    var tasks = new List<Task>();
    for (int i = 0; i < 10; i++)
    {
        tasks.Add(DoAsyncThing());
    }

    await Task.WhenAll(tasks);
    await SaveAll();
    Console.WriteLine("Saved");
}

public static void Main()
{
    ProcessAll().Wait();
    Console.WriteLine("sdf");
}

Вывод

waiting
waiting
waiting
waiting
waiting
waiting
waiting
waiting
waiting
waiting
waited
waited
waited
waited
waited
waited
waited
waited
waited
waited
Saving
Saved
sdf

Все задачи были выполнены.

0 голосов
/ 28 декабря 2018

Как насчет использования Task.Factory.StartNew();

Task.Factory.StartNew(() =>
{
     return DoAsyncThing();
}).ContinueWith(x =>
{
     if (x.Result)
        SaveAll();
});

, если DoAsyncThing() сделать что-то с пользовательским интерфейсом, вы должны использовать TaskScheduler.FromCurrentSynchronizationContext() с StartNew()

Надеюсь, это поможет.

Спасибо.

...