gpt4 book ai didi

c# - 异步等待、异常处理和继续使用 TaskContinuationOptions.OnlyOnFaulted

转载 作者:太空宇宙 更新时间:2023-11-03 18:30:22 26 4
gpt4 key购买 nike

我有以下示例控制台应用程序代码,但从未调用使用 TaskContinuationOptions.OnlyOnFaulted 的任务继续中指定的方法。

using System;
using System.Threading;
using System.Threading.Tasks;

namespace Sample
{
class Program
{
public static void Main(string[] args)
{
int index = 0;
var cts = new CancellationTokenSource();

Task.Factory.StartNew(() => NewTask(index), cts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default)
.ContinueWith(HandleException, cts.Token, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);

// Some code
// ...

Console.ReadLine();
}

private static async Task NewTask(int index)
{
Console.WriteLine(index);
await Wait();
}

private static async Task Wait()
{
await Task.Delay(500);
throw new Exception("Testing 123");
}

private static void HandleException(Task task)
{
if (task != null && task.Exception != null)
{
var exceptions = task.Exception.Flatten().InnerExceptions;
if (exceptions != null)
foreach (var exception in exceptions)
Console.WriteLine(exception.Message);
}
}
}
}

这里,当 Wait() 方法抛出异常时,而不是调用 HandleException(...) 时,程序崩溃或调试器显示未处理的异常对话框。

已编辑: NewTask 方法的返回类型是 Task

最佳答案

调用 Factory.StartNew ,您实际上正在创建一个任务,其方法主体只是启动您的实际任务,但您的实际任务没有继续;只有外部的、多余的任务(不会抛出异常)有一个。

此外,您的异步函数是 async void .这使得无法添加延续。我要更进一步说你永远不应该创建一个 async void 的函数。它应该总是 async Task .

如果您更改语法,您的调用语法实际上会更简单:

NewTask(index).ContinueWith(HandleException, cts.Token, 
TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.Default);

但是请记住,取消并不是免费的;您要么需要将您的 token 传递给其他使用它的异步任务,要么您需要自己检查它(或调用 .ThrowIfCancellationRequested())。

顺便说一句,按照惯例,任何返回 Task 的函数或 Task<T>其名称应以 Async 结尾(即它应该被命名为 NewTaskAsync )。

关于c# - 异步等待、异常处理和继续使用 TaskContinuationOptions.OnlyOnFaulted,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23351618/

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