在先前的异步操作之前,在此上下文中开始第二次操作

时间:2019-08-14 08:40:46

标签: c#

我有两个异步功能。

  1. WriteActionToActionLog

    • 记录要记录的操作
    • 将行添加到数据库
    • 异步保存
  2. 保存设置

    • 更新数据库中的行。
    • 通过异步列表拉两行
    • 通过简单的逻辑更新它们
    • 保存异步。

两者都是异步的。包裹着交易。将两个任务都添加到任务数组。使用whenAll

为了减少代码量,我将编写/*logic*/

同时我写了它,因为延迟很小,但是在我看来,使用并行任务更正确。

试图使用waitAll代替whenAll。但是答案没有回来。 尝试将SaveSetting函数中的异步列表转换为已同步。遇到相同的错误

.NET Framework是4.6.1

public async Task<myObject> wrapperFunc(InnerServiceSettings clientSettings) {
   DbModel DB = new DbModel();  

   using (var transaction = DB.Database.BeginTransaction())
   {
      try
      {
         var tasks = new List<Task>();    

         /*logic - typeActionList created */     

         var settingsTask =  SettingsManager.SaveSetting(DB, clientSettings);
         tasks.Add(settingsTask);

         var logTask = AdminManager.WriteActionToActionLog(DB, typeActionList, clientSettings.idNum);
         tasks.Add(logTask);

         Task[] taskArr = tasks.ToArray();
         await Task.WhenAll(logTask, settingsTask); //exception thrown

         transaction.Commit();
         /*logic*/
      }
      catch(exception ex) {... rollback etc...}
   }    
}

public async static Task<bool> SaveSetting(DbModel iDb, ClientSettings iSettings)
{
   //list to be updated at db. One pull from db instead of several pulls. Also tried to made its sync, leaving save async. 
   //will return two rows from DB  
   var objListToChange = await iDb.Settings.Where(x => … ).ToListAsync();

   /*logic*/
   if (..)
   {
      var rowAtoUpdate = objListToChange.Where(x => …).FirstOrDefault();
      rowAtoUpdate.return_day = (short)iSettings.return_dayA;
   }

   if (…)
   {
      var rowBtoUpdate = objListToChange.Where(…).FirstOrDefault();
      rowBtoUpdate.return_day = (short)iSettings.return_dayB;                
   }

   try
   {
      var x = await iDb.SaveChangesAsync();
      return true;
   }
   catch (Exception e)
   {
      throw e;
   }
}

public async static Task<bool> WriteActionToActionLog(DbModel iDb, List<Tuple<int, int>> iActionTypeValue, int iManagerIdNum)
{    
   var ActionListToAdd = new List<ManagersActionLog>();

   foreach(var tupElem in iActionTypeValue)
   {
      ActionListToAdd.Add(new ManagersActionLog
      {
         ActionType = tupElem.Item1,
         ActionValue = tupElem.Item2,
         LogDate = DateTime.Now,
         ManagerId = iManagerIdNum,
      });
   }


   try {                   
      iDb.ManagersActionLog.AddRange(ActionListToAdd);
      var ans =  await iDb.SaveChangesAsync();
      return true;
   }
   catch(Exception ex) {
      throw ex;
   }
}

一旦达到whenAll,我将得到: 在先前的异步操作完成之前,第二操作在此上下文上开始。使用await确保在此上下文上调用另一个方法之前,所有异步操作都已完成。不保证任何实例成员都是线程安全的。

0 个答案:

没有答案