gpt4 book ai didi

c# - 在任务中处理异常的正确方法 continuewith

转载 作者:IT王子 更新时间:2023-10-29 03:49:31 28 4
gpt4 key购买 nike

请看下面的代码-

static void Main(string[] args)
{
// Get the task.
var task = Task.Factory.StartNew<int>(() => { return div(32, 0); });

// For error handling.
task.ContinueWith(t => { Console.WriteLine(t.Exception.Message); },
TaskContinuationOptions.OnlyOnFaulted);

// If it succeeded.
task.ContinueWith(t => { Console.WriteLine(t.Result); },
TaskContinuationOptions.OnlyOnRanToCompletion);
Console.ReadKey();
Console.WriteLine("Hello");
}

private static int div(int x, int y)
{
if (y == 0)
{
throw new ArgumentException("y");
}
return x / y;
}

如果我在 Release模式下执行代码,输出是“发生一个或多个错误”,一旦我按下“Enter”键,“Hello”也会显示出来。如果我在 Debug模式下运行代码,输出和release模式一样,但是在IDE中调试时,控件执行该行时会出现IDE异常信息("Unhandled exception in user code")

throw new ArgumentException("y"); 

如果我从那里继续,程序不会崩溃并显示与 Release模式相同的输出。这是处理异常的正确方法吗?

最佳答案

您可能不需要单独的 OnlyOnFaultedOnlyOnRanToCompletion 处理程序,并且您不需要处理 OnlyOnCanceled。检查this answer更多细节。

But when debugging in IDE, A IDE exception message ("Unhandled exception in user code" ) appears when the control executes the line

您在调试器下看到异常,因为您可能已经在调试/异常选项中启用了它(Ctrl+Alt+E)。

If I continue from there on, the program does not crash and displays the same output as release mode. Is this proper way to handle exception?

Task 操作中抛出但未处理的异常不会自动重新抛出。相反,它被包装为 Task.Exception(AggregateException 类型)以供将来观察。您可以作为 Exception.InnerException 访问原始异常:

Exception ex = task.Exception;
if (ex != null && ex.InnerException != null)
ex = ex.InnerException;

要使程序在这种情况下崩溃,您实际上需要在任务操作之外观察异常,例如通过引用 Task.Result:

static void Main(string[] args)
{
// Get the task.
var task = Task.Factory.StartNew<int>(() => { return div(32, 0); });

// For error handling.
task.ContinueWith(t => { Console.WriteLine(t.Exception.Message); },
TaskContinuationOptions.OnlyOnFaulted);

// If it succeeded.
task.ContinueWith(t => { Console.WriteLine(t.Result); },
TaskContinuationOptions.OnlyOnRanToCompletion);

Console.ReadKey();

Console.WriteLine("result: " + task.Result); // will crash here

// you can also check task.Exception

Console.WriteLine("Hello");
}

更多详情:Tasks and Unhandled Exceptions , Task Exception Handling in .NET 4.5 .

已更新以解决评论:这是我在使用 .NET 4.0 和 VS2010 的 UI 应用程序中执行此操作的方法:

void Button_Click(object sender, EventArgs e)
{
Task.Factory.StartNew<int>(() =>
{
return div(32, 0);
}).ContinueWith((t) =>
{
if (t.IsFaulted)
{
// faulted with exception
Exception ex = t.Exception;
while (ex is AggregateException && ex.InnerException != null)
ex = ex.InnerException;
MessageBox.Show("Error: " + ex.Message);
}
else if (t.IsCanceled)
{
// this should not happen
// as you don't pass a CancellationToken into your task
MessageBox.Show("Canclled.");
}
else
{
// completed successfully
MessageBox.Show("Result: " + t.Result);
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}

只要您的目标是 .NET 4.0 并且您希望 .NET 4.0 的行为用于未观察到的异常(即,当任务被垃圾收集时重新抛出),您应该显式配置它app.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<runtime>
<ThrowUnobservedTaskExceptions enabled="true"/>
</runtime>
</configuration>

检查此以获取更多详细信息:

Unobserved task exceptions in .NET4

关于c# - 在任务中处理异常的正确方法 continuewith,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21520869/

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