gpt4 book ai didi

c# - try catch 异步异常

转载 作者:太空狗 更新时间:2023-10-29 17:55:30 24 4
gpt4 key购买 nike

这个例子“失败”了:

static async void Main(string[] args)
{
try
{
await TaskEx.Run(() => { throw new Exception("failure"); });
}
catch (Exception)
{
throw new Exception("success");
}
}

也就是说,带有文本“失败”的异常冒泡。

然后我尝试了这个解决方法:

static async void Main(string[] args)
{
try
{
await SafeRun(() => { throw new Exception("failure"); });
}
catch (Exception)
{
throw new Exception("success");
}
}

static async Task SafeRun(Action action)
{
var ex = default(Exception);
await TaskEx.Run(() =>
{
try
{
action();
}
catch (Exception _)
{
ex = _;
}
});
if (ex != default(Exception))
throw ex;
}

这也没有帮助。

我想我的 Async CTP 刷新安装可能会受到影响。

这段代码是否应该像我预期的那样工作(“成功”冒泡,而不是“失败”),或者这不是“应该”那样工作。如果没有,您将如何解决?

最佳答案

您看到的行为很可能是边缘情况错误,或者甚至可能是正确的,如果不直观的话。通常当你同步调用一个异步方法时,它会包装一个任务来执行,因为没有人在等待任务完成,所以异常永远不会进入主线程。如果您直接调用 Main,它会成功,但您的运行时会在另一个线程上看到“成功”异常。

由于 main 是您的应用程序的入口点,它是同步调用的,并且很可能因为入口点不会触发 Task 包装行为,所以 await 无法正常运行并且 TaskEx.Run 在它自己的线程上抛出,这在运行时显示为在另一个线程上抛出的异常。

如果您将 main 作为 async 方法运行,即返回一个 Task(因为 async 返回 void 只能通过 await) 真正调用并从同步主上下文中阻塞它,您将获得适当的行为,如下面的测试所示:

static async Task Main() {
try {
await TaskEx.Run(() => { throw new Exception("failure"); });
} catch(Exception) {
throw new Exception("success");
}
}

static async Task Main2() {
await Main();
}

[Test]
public void CallViaAwait() {
var t = Main2();
try {
t.Wait();
Assert.Fail("didn't throw");
} catch(AggregateException e) {
Assert.AreEqual("success",e.InnerException.Message);
}
}


[Test]
public void CallDirectly() {
var t = Main();
try {
t.Wait();
Assert.Fail("didn't throw");
} catch(AggregateException e) {
Assert.AreEqual("success", e.InnerException.Message);
}
}

即Task 出现 AggregateException 故障,其中包含 success 异常,因为它是内部异常。

关于c# - try catch 异步异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6377150/

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