异步任务之间的依赖关系

时间:2016-01-25 12:24:04

标签: c# asynchronous async-await

我多次调用异步方法,每个单元调用

var tasks = otherData.Select(async unit =>
  await OneUnitProcessor.ProcessOneUnitAsync(
    var1,
    authenticationResponse,
    unit,
    reservation: new Reservation()
  )
);

await Task.WhenAll(tasks);

这是我的异步方法:

 public static async Task ProcessOneUnitAsync(string var1, ServiceResponse authenticationResponse, ChannelManagerJsonHolder unit,IReservation reservation, CookieCollection cookieCollection = null)
    {
 List<Task<HttpResponseMessage>> tasksDeleteReservations = reservation.DeleteReservations(allLinksToDelete, authenticationResponse, unit);


 var occupiedPricesItems = OccupationPriceGetter.GetOccupiedPeriodsWithPrices(fiksniTecaj,   authenticationResponse, unit, cookieCollection);


 tasksOccupied = allOccupationsToInsert.Select(async price => await Api.CalendarPrices.SendRequestAsync(authenticationResponse, unit, price, unavailable: true));

 await Task.WhenAll(tasksOccupied.Union(tasksDeleteReservations));
 }

基本上有一些任务会删除保留(tasksDeleteReservations)和插入保留的任务(tasksOccupied)。这个解决方案对我不利,因为我想要实现所有&#34; old&#34;在插入新的保留之前删除保留(所有tasksDeleteReservations任务在tasksOccupied之前完成)

一种解决方案是在我的异步方法中有两个等待,但我不认为它是好的解决方案两个有多个等待(控制将返回到调用者,我认为程序将在所有其他任务之前退出(与插入预订有关)已完成。 其他解决方案是在继续插入之前阻止删除,但这可能不再是异步代码。 如何在这种情况下实现异步性和执行顺序?

EDIT1:这是调用处理所有单元的任务的代码;

   private async Task ProcessAllUnits(string var1, IEnumerable<ChannelManagerJsonHolder> otherData, ServiceResponse authenticationResponse)
    {

        try
        {
            var tasks = otherData.Select(async unit => await OneUnitProcessor.ProcessOneUnitAsync(fiksniTecaj, authenticationResponse, unit, reservation: new Reservation()));
            await Task.WhenAll(tasks);
        }
        catch (AggregateException ex)
        {
            foreach (var innerException in ex.InnerExceptions)
            {
                new FileLogger().Log("Unit level exception:" + innerException.Message, ChannelManager.Core.Utilities.Logging.LogLevel.Error);
            }

        }

    }

ProcessAllUnits由其他一些方法调用。以下是该方法的代码:

  private async Task LoginAndProcessAllUnits(string var1, UserModel     oneGroupedCMJsonHolder,IAuthentication authentication)
 {
 var task = ProcessAllUnits(fiksniTecaj, otherData, authenticationResponse);
                await task;
   }

这是顶级方法:

public  void ProcessAllUsersAsync(List<ChannelManagerJsonHolder>    CMJsonHolder, string var1)
        {
 var tasks = new List<Task>();
              foreach (var group in groupedCMJsonHolder)
             {
                  var task = LoginAndProcessAllUnits(fiksniTecaj, group, new    Authentication());
                   tasks.Add(task);
            }
              Task.WaitAll(tasks.ToArray());

}

2 个答案:

答案 0 :(得分:2)

您需要的只是两个等待这些任务集合。控制确实返回到调用者,但任务未完成。如果任务是通过使用等待该功能有什么好处完成的?!这相当于return的作用。

async unit => ...开头的任务也只有在OneUnitProcessor.ProcessOneUnitAsync...任务完成后才会完成。

完成所有这些任务后await Task.WhenAll(tasks);已完成。

await用于序列化任务的执行。

答案 1 :(得分:2)

在一种方法中使用多个QNetworkInterface eth1Ip = QNetworkInterface::interfaceFromName("eth1"); QList<QNetworkAddressEntry> entries = eth1Ip.addressEntries(); if (!entries.isEmpty()) { QNetworkAddressEntry entry = entries.first(); qDebug() << entry.ip(); } 并没有错。事实上,这就是为什么你首先使用await,真的 - 为你管理状态机和延续。

是的,控件将返回给调用者。但关键是,如果您使用的是await,则需要一直使用await - 您所描述的行为只会在您的await链被一些人破坏时发生某些异步方法上没有await的方法。这就是问题所在,而不是await多次async方法。