我有一个执行以下任务的任务:
CancellationTokenSource cancelToken = new CancellationTokenSource();
Task createEntity = Task.Run(async () =>
{
try
{
await _clearerStagingService.SaveNewClearer(clearerStaging);
}
catch (Exception ex)
{
cancelToken.Cancel();
Logger.SendError($"Failed to save", ex);
}
}, cancelToken.Token);
如您所见,发生错误时将调用取消令牌。这是因为我希望线程在失败时退出-这是在失败时安全退出线程的正确方法吗?
然后,我实现了以下代码,该代码仅应在成功运行以上线程时运行:
createEntity.Wait(cancelToken.Token);
if (!cancelToken.IsCancellationRequested)
{
Task.Run(async () =>
{
try
{
await _auditService.CreateAudit(audit);
}
catch (Exception ex)
{
Logger.SendError("Could not create Audit.", ex);
}
});
}
我不确定这是否是实现取消令牌的方法,我尝试环顾四周,但感到很困惑。
一些帮助,将不胜感激。
答案 0 :(得分:0)
为什么不简单:
Task.Run(async () =>
{
try
{
await _clearerStagingService.SaveNewClearer(clearerStaging);
await _auditService.CreateAudit(audit);
}
catch (Exception ex)
{
}
});
如果SaveNewClearer
引发异常,则CreateAudit
之后CreateAudit
将不会运行,并且CreateAudit
将运行 。 await
操作发生时,async
将“暂停”任务,然后在任务被暂停的同一位置返回时,任务将继续执行。
如果发生任何故障,Task
将自然终止,而无需任何取消标记。
我不能说服您需要Task.Run()
TBH,但我不知道WPF,所以我想这是有充分的理由的,也许不阻止UI线程?
答案 1 :(得分:0)
是的,这有点人为。但是,让async
为async
这些方法没有取消标记,因此在您的情况下(貌似)拥有一个没有优势。这行不通吗?
public async Task DoSomething()
{
await _clearerStagingService.SaveNewClearer(clearerStaging);
await _auditService.CreateAudit(audit);
}
答案 2 :(得分:0)
根据Liam的回答,您不必每次为每个语句创建单独的任务
当您已经通过createEntity.Wait(cancelToken.Token);
try
{
await _clearerStagingService.SaveNewClearer(clearerStaging);
await _auditService.CreateAudit(audit);
}
catch (Exception ex)
{
}
我还要添加有关CancellationTokenSource的信息
仅在要明确取消任务时才需要CancellationTokenSource
,否则无需使用CancellationTokenSource.Token