【发布时间】:2018-11-01 18:11:39
【问题描述】:
我有以下一段代码,我首先运行查询并添加原始结果ViewModel.RawContracts.AddRange(contractResults);
然后我想用多个不同的数据源来丰富这组数据,例如_enrichmentHelper.ResolveSecurities(token, contractsToEnrich); 这些方法中的所有扩充本身都是异步完成的。
完成所有这些丰富后,我想运行最后一段代码来获取现在丰富的原始数据,并将其添加到我的网格ViewModel.ContractRows.AddRange(ViewModel.RawContracts);
但是,我的最终继续 queryAndEnrichmentTask 在查询任务完成后执行,而不是在每个扩充继续完成之后执行。
我在这里做错了什么?
Task.Factory.StartNew
(
() =>
{
Log.Debug("Starting getting contracts");
Task queryTask = _serviceModel.GetContractsByCriteriaAsync(token, ViewModel.QueryRequest)
.LogExceptions()
.ContinueWith
(
prevTask =>
{
if (!token.IsCancellationRequested)
{
IQueryResponse response = null;
Log.Debug("Received contract response.");
if (prevTask.IsFaulted || (response = prevTask.Result) == null)
{
ViewModel.ErrorMessage = "Failed to load contracts. Please check the log file for details.";
}
else
{
if (response.Contracts != null)
{
Log.Debug($"Start loading {response.Contracts.Count()} contract positions...");
bool successful = true;
if (successful && prevTask.IsCompleted && prevTask.Result != null)
{
contractResults = prevTask.Result.Contracts.ToList();
ViewModel.RawContracts.Clear();
ViewModel.RawContracts.AddRange(contractResults);
}
Log.Debug("Finished loading contracts");
}
}
}
Log.Debug("Finished loading contracts");
}, token, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default
); // End add raw results task
IList<IContract> contractsToEnrich = ViewModel.RawContracts;
queryTask.ContinueWith(prevTask =>
{
_enrichmentHelper.ResolveSecurities(token, contractsToEnrich);
}, token, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
queryTask.ContinueWith(prevTask =>
{
_enrichmentHelper.ResolveBooks(token, contractsToEnrich);
}, token, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
queryTask.ContinueWith(prevTask =>
{
_enrichmentHelper.ResolveCounterparties(token, contractsToEnrich);
}, token, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
queryTask.ContinueWith(prevTask =>
{
_enrichmentHelper.ResolveLegalEntities(token, contractsToEnrich);
}, token, TaskContinuationOptions.AttachedToParent | TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
}, token
)
.LogExceptions()
.ContinueWith
(
queryAndEnrichmentTask =>
{
Log.Debug("Post search task started");
if (queryAndEnrichmentTask.IsFaulted)
{
if (!ViewModel.HasErrorMessage)
ViewModel.ErrorMessage = "Error occured when loading data. Please refer to log file for details";
}
else
{
ViewModel.ContractRows.AddRange(ViewModel.RawContracts);
}
Log.Debug("Post search task completed");
}, token, TaskContinuationOptions.NotOnCanceled, TaskScheduler.Default)
.LogExceptions();
【问题讨论】:
-
你应该很少使用
ContinueWith。使用await为任务添加延续。正确编写远更容易,并且使您很难诊断代码中的错误的可能性大大降低。在极少数情况下,ContinueWith是需要或可取的。 -
不同意从不使用
ContinueWith。使用您的团队、正在使用的库和/或您自己的经验定义的约定。