异步运行C#WPF事件

时间:2019-03-10 13:51:25

标签: c# wpf asynchronous events

我一直在努力处理WPF应用程序事件的处理方式。可能以前已经回答了这个问题,但是我所有的搜索都导致答案太复杂,以至于我听不懂或者只是有点话题。但是我的理解是这些事件是同步运行的。

这是什么原因?以及为什么它们不只是异步的?是否可以强制应用程序异步运行它们中的全部?

谢谢!

2 个答案:

答案 0 :(得分:0)

引发事件时,将依次调用其处理程序。它们默认情况下不是异步的原因是,这将产生不必要的开销,并且难以实现。对于.NET中的所有事件,此行为均是如此,与WPF无关。

只有一个线程可以访问WPF中的UI。 WPF中的所有UI事件均从此UI线程引发。如果处理程序需要花费很长时间执行,则UI线程将被阻塞,直到处理程序完成执行为止,从而导致应用程序处于“挂起”状态。原因不在此问题的范围之内,应该进行完整的单独解释。

认为事件是否同步是不正确的。同步或异步处理程序。因此,不可能仅在您的应用中指定默认情况下所有事件都是异步的。但是可以使所有(或某些)事件处理程序异步。

使事件处理程序异步非常容易-只需将其标记为asyncawait即可长时间运行。您可以了解有关asyncawait here的更多信息。

异步事件处理程序不会阻塞UI线程,因为它们是在其他线程中执行的(嗯,实际上它要复杂得多,但这是一般的想法)。

答案 1 :(得分:0)

当您对您说“应用程序事件”时,仅指System.Windows.Application上定义的那些事件吗?还是您只是说任何ANY类中已声明的event成员?

该事件是方法委托的集合:当类引发某些事件时,它只是开始调用处理程序。如果那是异步的,则该事件的生产者将不知道任何人可能会处理该事件,并且无法实现像Window.Closing这样的可取消事件---无法保证任何处理程序都可以同步运行,并且生产者可以总是经历不可取消的事件;使那没用。

消费者也不会知道他们何时参加比赛!如果引发了一个属性更改事件,则可能在该属性更改了很多次之后很久才被调用,谁又知道当时应用程序在哪里!

许多事件被设计为同步处理:应用程序刚刚达到某种状态,如果您无法同步处理事件,那么它是无用的---这就是事件WAS引发开始的原因

如果事件在默认情况下是异步的,那么它们将成为易于访问的异步“消息总线”,并且我认为,如果您回头看一下,就会发现这是一种“浪费时间”。如果作为事件生产者您能做的就是解雇一些异步未知通知,那您为什么还要打扰呢?那时,生产者还可以“抱怨”为每个活动实现一些异步消息,即,您如何提出引发事件的定义? (您会在哪里停止所有活动;可以考虑通过工具实施该活动。)

其中包含许多带有“应用程序消息总线”实现的库。使用单个应用程序范围的异步消息总线,那么您可能会有一些服务概念,可以向其“提供”事件通知。如果您更清楚地将此事物定义为生产者发布消息且消费者可以订阅它们的地方,那么您对服务的更多概念可以实现和使用。您可以为您的应用程序创建一个,订阅现有事件,然后将其发布到那里,供异步使用方处理...

如果您可以将特定事件设计为对异步实现有用,那么您现在可以自己选择定义异步事件,而不是默认情况下的异步。 ---重复:默认情况下,您将永远无法可靠地知道WHO将在何时处理事件。

您还可以使用新的Async版本重新定义任何现有事件,并添加一个将每个事件重新发布到异步服务的同步处理程序……但是,一切都取决于需要事件的设计以某种异步的方式而“默认”异步事件将开始被遗忘,并且对于生产者来说,噩梦一直困扰着他们,生产者将永远不会知道它们引发的事件发生了什么(并且无法以不变的方式对其进行调试)。

...“ Mvvm”库中有事件总线;像MVVM Light。