我有两个异步功能。
WriteActionToActionLog
保存设置
两者都是异步的。包裹着交易。将两个任务都添加到任务数组。使用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
确保在此上下文上调用另一个方法之前,所有异步操作都已完成。不保证任何实例成员都是线程安全的。