仅在另一个任务成功完成时运行任务

时间:2018-07-25 09:59:33

标签: c# wpf multithreading

我有一个执行以下任务的任务:

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);
            }
        });
    }

我不确定这是否是实现取消令牌的方法,我尝试环顾四周,但感到很困惑。

一些帮助,将不胜感激。

3 个答案:

答案 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)

是的,这有点人为。但是,让asyncasync

这些方法没有取消标记,因此在您的情况下(貌似)拥有一个没有优势。这行不通吗?

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