gpt4 book ai didi

c# - 为什么即使处理程序在 WPF 应用程序生命周期中是异步无效的,Application.Exit 事件仍然有效?

转载 作者:太空狗 更新时间:2023-10-30 00:19:36 32 4
gpt4 key购买 nike

我有一个问题如何在 WPF 生命周期方法(使用 Caliburn-Micro 框架)中等待异步方法(例如 OnActivate、OnInitialized、OnExit - 直接绑定(bind)到 Application.Exit 事件)

这篇文章准确描述了我的问题:http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void (现在我正在考虑使用本文中的解决方案,但乍一看似乎有点矫枉过正)

我需要在我的 OnExit 处理程序中等待一些异步方法,所以我将它作为异步方法。它有效。的种类。我不明白为什么??,但在调用 Application.Exit 事件时,它会以某种方式等待直到方法完成,即使处理程序是异步无效的。 你能解释一下这是怎么可能的吗?这安全吗?还是只是巧合?Async void 应该只用于顶级事件,是这种情况吗?

我查看了系统的代码。绑定(bind)看起来像这样:

public event EventHandler Exit
{
add
{
XcpImports.CheckThread();
this.AddEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
}
remove
{
XcpImports.CheckThread();
this.RemoveEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
}
}

这真的很神秘,我无法通过调用此事件看到 .net Framework 中真正发生了什么。

同样奇怪的是,当我不使用 ConfigureAwait(false) 时,在处理程序中调用 await Task.Delay(1) 会导致死锁。所以我会说在 .net 代码中有某个地方使用了 .Wait()

注意:当我使 OnActivate、OnInitialized 处理程序异步时,正如预期的那样,页面不会等到处理程序完成。

感谢您的回答!

最佳答案

理论上,框架可以检测到 async void 的使用并等待 async void 方法返回。我在我的 article on SynchronizationContext 中描述了细节.据我所知,ASP.NET 是唯一会等待 async void 处理程序的内置框架。

WPF async void 方法有任何特殊处理。因此,您的退出处理程序正在完成这一事实只是巧合。我怀疑您 await 的操作已经完成或非常快,这允许您的处理程序同步完成。

也就是说,我不推荐您引用的文章中的解决方案。相反,处理窗口的 Closing 事件,启动您需要执行的任何异步保存,并取消关闭命令(并考虑立即隐藏窗口)。当异步操作完成后,再次关闭窗口(并允许它关闭这次)。我使用这种模式来执行异步窗口级“关闭”动画。

我无法重现您描述的僵局。我创建了一个新的 .NET 4.5 WPF 应用程序并添加了一个退出处理程序:

private async void Application_Exit(object sender, ExitEventArgs e)
{
await Task.Delay(1);
}

但没有观察到死锁。事实上,即使使用 Task.Yieldawait 之后也不会执行任何操作,这正是我所期望的。

关于c# - 为什么即使处理程序在 WPF 应用程序生命周期中是异步无效的,Application.Exit 事件仍然有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18637395/

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