gpt4 book ai didi

c# - 任务取消异常 (ThrowForNonSuccess)

转载 作者:太空狗 更新时间:2023-10-29 18:27:00 26 4
gpt4 key购买 nike

这是这个问题的延续: 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() 只是关闭表单。如果我删除该行,则会发生同样的事情。

最佳答案

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

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

您的 2 个代码片段之间的区别在于,在第一个代码片段中,您 await 任务继续,它们被取消,这解释了您的异常。在第二个片段中,您不等待延续,只等待成功运行完成的原始任务。

P.S:我觉得第二种更合适。您不需要 await 所有这些延续。如果需要,您想让它们运行。

TL;DR:您await 一个已取消的延续任务。继续任务,而不是原始任务,是抛出异常的任务。

关于c# - 任务取消异常 (ThrowForNonSuccess),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21190552/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com