为什么Application.Exit事件的工程,即使处理程序是异步虚空中WPF应用程序生命周期? [英] Why Application.Exit event works even if handler is async void in WPF application lifecycle?

查看:190
本文介绍了为什么Application.Exit事件的工程,即使处理程序是异步虚空中WPF应用程序生命周期?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,如何在等待WPF生命周期方法异步方法(与卡利微架构)(如OnActivate,OnInitialized,OnExit - 这直接绑定到 Application.Exit 事件)

I have a problem how to await async methods in WPF life-cycle methods (with Caliburn-Micro framework) (eg. OnActivate, OnInitialized, OnExit - which is bound directly to Application.Exit event)

本文正是描述了我的问题:<一href=\"http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void\" rel=\"nofollow\">http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void (现在我想用从本文的解决方案,但似乎有点矫枉过正先看看)

This article exactly describes my problem: http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void (now I am thinking of using the solution from this article, but seems like a bit overkill for the first look)

我要等待我的OnExit hanlder一些异步方法,所以我把它当作异步。和它的作品。有点。
我不明白的为什么?? ,但在调用Application.Exit事件以某种方式等待,直到方法完成,即使处理程序是异步无效。的你能解释一下请这怎么可能?而就是这样安全吗?或者只是coicidence?的异步无效,应仅适用于的顶级的事件中使用,这是一个情况?

I need to await some async methods in my OnExit hanlder so I have it as async. And it works. Kind of. I do not understand why??, but on calling Application.Exit event it somehow waits until the method is completed, even if the handler is async void. Can you explain please how this is possible? And is this safe? Or is it just coicidence? Async void should be used only for Top-Level events, is this that case?

我看着在系统的code。并且绑定这个样子的:

I looked in the code of System. And the binding looks like this:

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中到底发生了什么。

which is really cryptic and I cannot see what really happens in .net framework by calling this event.

什么是也奇怪,在调用的等待Task.Delay(1)的处理程序引起了死锁当我不使用的 ConfigureAwait(假)的。所以,我要说是在某个地方的 .Wait()的使用.NET code系列。

What is as well strange, that calling await Task.Delay(1) in the handler causes DeadLock when I do not use ConfigureAwait(false). So I would say there is somewhere .Wait() used deep in .net code.

请注意:当我做OnActivate,OnInitialized处理异步,符合市场预期,页面未等到处理程序完成

Note: when I make OnActivate, OnInitialized handlers async, as expected, page is not waiting till handler completes.

THX为您answeres!

Thx for your answeres!

推荐答案

这在理论上是可能的框架,以检测异步无效使用并等待异步无效方法返回。我描述的的SynchronizationContext 文章的细节一>。据我所知,ASP.NET是唯一内置框架,将等待异步无效处理程序。

It is theoretically possible for a framework to detect the use of async void and wait until the async void method returns. I describe the details in my article on SynchronizationContext. AFAIK, ASP.NET is the only built-in framework that will wait on async void handlers.

WPF做的的有异步无效方法的任何特殊待遇。因此,事实上,你的出口处理程序完成仅仅是巧合。我怀疑你的操作等待要么已经完成或速度极快,这使得你的处理器同步完成。

WPF does not have any special treatment for async void methods. So the fact that your exit handler is completing is just coincidence. I suspect that the operations you await are either already complete or extremely fast, which allows your handler to complete synchronously.

这是说,我不建议你提到的文章中的解决方案。相反,处理窗口的结束事件,打完折无论异步节省你需要做的,并取消了关闭命令(并考虑立即隐藏窗口)。当异步操作完成时,然后再次关闭该窗口(并允许它以关闭这个时间)。我用这个模式做异步窗口级别关闭的动画。

That said, I do not recommend the solution in the article you referenced. Instead, handle the window's Closing event, kick off whatever asynchronous saving you need to do, and cancel the close command (and also consider hiding the window immediately). When the asynchronous operation is complete, then close the window again (and allow it to close this time). I use this pattern for doing asynchronous window-level "close" animations.

我不能瑞普你描述的僵局。我创建了一个新的.NET 4.5的WPF应用程序,并增加了退出处理这样:

I'm unable to repro the deadlock you describe. I created a new .NET 4.5 WPF application and added an exit handler as such:

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

但并没有观察到死锁。事实上,即使使用 Task.Yield ,没有经过等待是不断执行,这正是我所期望的

but did not observe a deadlock. In fact, even with using Task.Yield, nothing after the await is ever executed, which is what I would expect.

这篇关于为什么Application.Exit事件的工程,即使处理程序是异步虚空中WPF应用程序生命周期?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆