gpt4 book ai didi

c# - 如何在 MonoTouch 中使用 async/await 忽略未观察到的异常?

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

在以前版本的 MonoTouch 中,我曾经这样做来忽略未观察到的异常:

TaskScheduler.UnobservedTaskException += delegate(object sender, UnobservedTaskExceptionEventArgs e) {
Console.WriteLine (e);
e.SetObserved ();
};

这是否是一个好的做法值得商榷,但我想知道用 async/await 关键字实现同样的效果 now officially supported in Xamarin.iOS 6.4 .

这是我用来测试的代码:

async void OnClick (object sender, EventArgs e)
{
await Task.Run (() => { throw new Exception (); });
}

当我运行它时,调试器在 AsyncVoidMethodBuilder 中暂停:

enter image description here

我读到 .NET 4.5 应该是 changed the behaviour so unobserved exceptions don't crash the app — 但如果将异常发布到我无法处理的 UIKit 同步上下文,这将无济于事。

有没有办法在 MonoTouch 中忽略来自 await 的未观察到的异常?

最佳答案

这是 async void 方法的正确行为:它们应该在当时处于事件状态的 SynchronizationContext 上引发异常async void 方法启动。

您在 .NET 4.5 中提到的更改仅处理未观察到的 task 异常,不适用于 async void 方法。

在 (Microsoft) .NET 世界中,不同的 SynchronizationContext 实现具有不同的顶级错误处理。 WPF、WinForms 和 ASP.NET 都有不同的方法来处理该错误,通常作为 Application 类型的一部分。

我查看了 Mono 的 UIKit API - 虽然我不是普通的 Mono 用户 - 但在 UIApplicationUIKitSynchronizationContext 中找不到任何顶级错误处理看起来它不公开(或者至少没有记录)。

查看此问题的另一种方式:async void 方法的异常处理行为被设计为与事件处理程序 一样(有关详细信息,请参阅 my MSDN article ).所以你可以用另一个问题来回答这个问题:在 UIKit 中,你会如何处理这个异常?

void OnClick (object sender, EventArgs e)
{
throw new Exception();
}

您将以完全相同的方式处理您的 async void 异常。

或者,如果您想继续使用 UnobservedTaskException,您可以简单地不观察任务异常(在您的 async void 代码中,Task.Run 返回一个获取异常的任务,您正在使用 await 观察它):

void OnClick (object sender, EventArgs e)
{
Task.Run(() => { throw new Exception(); });
}

但是,我建议对事件处理程序使用 async void 并(最终)await 执行所有任务。这将确保您不会在程序停止正常工作而您不知道原因的情况下收到任何“无提示错误”(忽略的任务异常)。

关于c# - 如何在 MonoTouch 中使用 async/await 忽略未观察到的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17857812/

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