【问题标题】:Task Cancelled Exception (ThrowForNonSuccess)任务取消异常 (ThrowForNonSuccess)
【发布时间】:2014-01-17 16:11:21
【问题描述】:

这是这个问题的延续: Multiple Task Continuation

我已经按照答案更改了我的代码,但是现在我在尝试运行任务时收到TaskCancelledExceptions

public virtual async Task RunAsync(TaskWithProgress task)
{
    Show();
    TaskIsRunning();
    await SetCompletedHandler(TaskComplete());
    await SetCancelledHandler(TaskCancelled())
    await SetFaultedHandler(TaskFaulted());
    await task;
    Close();
}

但是下面的代码没有。我有点不知道为什么。

public virtual Task RunAsync(TaskWithProgress task)
{
    Show();
    TaskIsRunning();
    SetCompletedHandler(TaskComplete());
    SetCancelledHandler(TaskCancelled())
    SetFaultedHandler(TaskFaulted());
    return task;
}

调用代码主要涉及以下内容:

await progressDialog.RunAsync(task);

编辑:

我不会在任何地方取消cancellationtoken,所以我不明白为什么会抛出该异常。

三个SetXXXHandler()方法基本执行以下代码,不同的延续状态:

task.ContinueWith(_ => action(), CancellationToken.None, TaskContinuationOptions.OnlyOnCanceled, this.Scheduler);

堆栈跟踪在这里:

   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at FugroDXExt.frmBaseProgressAsync.<RunAsync>d__7.MoveNext() in d:\C#\FugroDXExt\trunk\frmBaseProgressAsync.cs:line 92
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
   at FCP.Forms.frmProcessing.<mnuApplyCenteredSmoothing_ItemClick>d__34.MoveNext() in d:\C#\FCP\FCP\Forms\frmProcessing.cs:line 578

Close() 只是关闭表单。如果我删除该行,也会发生同样的事情。

【问题讨论】:

  • 很可能,某处的某些代码正在取消CancellationToken
  • 这很奇怪,它不是。我解开了我的cancellationToken.Cancel(),它仍然会发生。
  • 什么是堆栈跟踪?那么 Close() 是什么意思呢?
  • 究竟是哪一行引发了异常?
  • 'await prog.RunAsync' 调用

标签: c# .net asynchronous task-parallel-library async-await


【解决方案1】:

你说SetCancelledHandler 只是为任务添加了一个延续。我假设这是 RunAsync 作为参数获取的相同任务,尽管我无法通过您的代码告诉 SetCancelledHandler 如何继续执行任务(我假设我们缺少一些代码)。总之……

您在一个任务上注册了 3 个延续,这些延续将在该任务完成、被取消和出现故障时运行。现在让我们假设原始任务成功运行并没有被取消。这意味着您的 2 个延续(OnCanceledOnFaulted)不会运行,因为它们不需要运行。在TPL 中告诉任务不要运行的方法是取消它,这会自动发生。

您的 2 个代码 sn-ps 之间的区别在于,在第一个代码中,您 await 任务继续,它们被取消,这解释了您的异常。在第二个 sn-p 上,您无需等待继续,而是等待成功运行完成的原始任务。

P.S:我认为第二种选择更合适。您不需要await 所有这些继续。如果需要,您想让它们运行。

TL;DR:您 await 取消了继续任务。延续任务,而不是原始任务,是引发异常的任务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-12
    • 1970-01-01
    相关资源
    最近更新 更多