当前位置: 首页 > 知识库问答 >
问题:

为什么应用程序退出事件有效,即使处理程序在 WPF 应用程序生命周期中异步无效?

羿昊英
2023-03-14

我有一个问题,如何在WPF生命周期方法(使用Caliburn-Micro框架)中等待异步方法(例如OnActivate、OnInitialized、OnExit),这些方法直接绑定到应用程序。退出事件)

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

我需要在我的OnExit hanlder中等待一些异步方法,所以我把它作为async。这很有效。算是吧。我不明白为什么??,而是在调用应用程序时。事件,它会一直等到方法完成,即使处理程序是异步void。你能解释一下这怎么可能吗?这安全吗?或者只是巧合?异步void应该只用于顶级事件,是这样吗?

我查看了系统的代码。绑定如下所示:

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框架中真正发生的事情。

同样奇怪的是,那个召唤等待任务。当我不使用configurewait(false)时,处理程序中的Delay(1)会导致死锁。所以我会说在某个地方。Wait()用在深处。net代码。

注意:当我使 OnActivate 时,按预期,OnInitialized 处理程序异步,页面不会等到处理程序完成。

谢谢你的回答!

共有1个答案

左丘宜然
2023-03-14

理论上,框架可以检测到< code>async void的使用,并等待< code>async void方法返回。我在关于< code > SynchronizationContext 的文章中描述了细节。async的AFAIK是唯一一个等待< code>async void处理程序的内置框架。

WPF对async val方法没有任何特殊处理。所以您的退出处理程序正在完成的事实只是巧合。我怀疑您等待的操作要么已经完成,要么速度极快,这允许您的处理程序同步完成。

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

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

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

但没有观察到僵局。事实上,即使使用<code>任务。Yield,在等待之后,不会执行任何操作,这就是我所期望的。

 类似资料:
  • Django为管理活动提供了一个随时可用的用户界面。 我们都知道管理界面对于Web项目很重要。 Django根据您的项目模型自动生成管理UI。 启动管理界面 Admin界面依赖于django.countrib模块。 要使其正常工作,您需要确保在myproject/settings.py文件的INSTALLED_APPS和MIDDLEWARE_CLASSES元组中导入一些模块。 对于INSTALLE

  • 项目是许多应用程序的总和。 每个应用程序都有一个目标,可以重复使用到另一个项目中,比如网站上的联系表单可以是一个应用程序,并且可以重用给其他人。 将其视为项目的一个模块。 创建一个应用程序 我们假设您在项目文件夹中。 在我们的主“myproject”文件夹中,相同的文件夹然后manage.py - $ python manage.py startapp myapp 你刚刚创建了myapp应用程序

  • 我有一个带post请求的控制器。我试图用一个简单的NotNull注释验证POJO。我正在使用ControllerAdvice来处理异常。 所以我尝试使用它,但当我启动应用程序时,我得到了以下信息: 因此,我想为BindException创建自己的处理程序,但当我为BindException类创建ExceptionHandler时,spring应用程序不会启动。如果我注释掉handleBindExc

  • 我在本地玩axon服务器。我正在本地计算机上通过命令运行一个docker容器。 当我启动spring-boot应用程序时,聚合外部的事件处理程序会重新运行所有以前的事件,因此在启动时会看到日志语句流。 注释似乎并不能阻止这种情况。此外,我试图按照这里的说明使处理程序成为事件处理器,但要么我做得不对,要么也没有解决问题。

  • 我正在开发一个需要在activiy中加载UnityPlayer实例的android应用程序,使用以下论坛帖子中的代码作为指南: http://forum.unity3d.com/threads/98315-Using-Unity-Android-In-a-Sub-View . 最初,应用程序在一个名为“UnityActivity.java”的活动中正确地显示了UnityPlayer。 当用户导航回

  • 您的网站“www.mywebsiteurl.com”尚未通过数字资产链接协议链接到您的应用程序。请通过数字资产链接协议将您的网站链接到您的应用程序。 您应该至少有一个活动的APK,该APK通过web“意图筛选器”映射到站点“www.mywebsiteurl.com”。 为了能够测试我的即时应用程序,我上传了我的可安装APK草稿。 以下是我的可安装应用程序的清单文件: 我将感谢你的帮助。谢了。