Prism 开发之五 消息引擎

1、前言  

  Prism库提供了一个事件机制,使应用程序中松散耦合的组件之间能够进行通信。此机制基于事件聚合器服务,允许发布商和订阅者通过事件进行通信,并且仍然没有直接引用对方。提供多播发布/订阅功能。这意味着可以有多个发布商提出相同的事件,也可以有多个订阅者收听同一事件。考虑使用该事件在模块之间发布事件,并在业务逻辑代码(如控制器和演示者)之间发送消息时。EventAggregatorPrism库创建的事件是键入事件。这意味着您可以利用编译时间类型检查来检测应用程序运行前的错误。在Prism库,允许订阅者或出版商找到一个特定的。事件聚合器还允许多个发布商和多个订阅者,如下图所示。EventAggregator  EventBase

使用事件聚合器

2、事件聚合器

 该类作为容器中的服务提供,可通过界面检索。事件聚合器负责定位或构建事件,并将事件集合保存在系统中。EventAggregator  IEventAggregator

public interface IEventAggregator { TEventType GetEvent<TEventType>() where TEventType : EventBase; }
如果事件尚未构建,则在第一次访问时构建该事件。这样发布者或订户就无需确定该事件是否可用。EventAggregator

3、案例说明

  连接发布商和订阅者的实际工作由组件完成。这是Prism库中唯一包含的类的实现。此类维护订阅者列表并处理向订阅者发送的事件。PubSubEventEventBase该类是一个通用类,要求将有效载荷类型定义为通用类型。这有助于在编译时间强制强制规定发布商和订阅者为成功事件连接提供正确的方法。以下代码显示了 PubSubEvent 类的部分定义。PubSubEvent

3.1 创建事件

  该课程旨在成为应用程序或模块特定事件的基础类。 是事件有效载荷的类型。有效载荷是当事件发布时将传递给订阅者的争论。

PubSubEvent<TPayload>TPayLoad

  例如,有效载荷是包含公司符号的字符串。请注意此类的实现如何是空的。TickerSymbolSelectedEvent

public class TickerSymbolSelectedEvent : PubSubEvent<string>{}

3.2 发布消息

发布者通过从该方法中检索事件并调用该方法来提出事件。要访问,您可以通过在类构造器中添加类型参数来使用依赖性注释。

public class MainPageViewModel { 
IEventAggregator _eventAggregator;

public MainPageViewModel(IEventAggregator ea) {
_eventAggregator = ea;
}
}
以下代码演示发布 Tickersymbol 选择事件。
_eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("STOCK0");

2.3 订阅事件

  订阅者可以使用类中可用的方法超载之一参加活动。SubscribePubSubEvent

public class MainPageViewModel {
public MainPageViewModel(IEventAggregator ea)
{
ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews);
}

void ShowNews(string companySymbol) { //implement logic } }
有几种方法可以订阅。使用以下标准帮助确定最适合您需求的选项:PubSubEvents
  • 如果您需要在收到事件时能够更新 UI 元素,请订阅在 UI 线程上接收事件。
  • 如果您需要筛选事件,请在订阅时提供筛选委托。
  • 如果您对事件有绩效问题,请考虑在订阅时使用强烈引用的代表,然后手动取消订阅 PubSubEvent。
  • 如果上述任何一项都不适用,请使用默认订阅。

以下部分描述了这些选项。

2.4 订阅 UI 线程

  通常,订阅者需要更新 UI 元素以响应事件。在 WPF 中,只有 UI 线程才能更新 UI 元素。默认情况下,订阅者会在发布商的线程上接收事件。如果发布者从 UI 线程发送事件,订户可以更新 UI。但是,如果发布器的线程是背景线程,则订阅者可能无法直接更新 UI 元素。在这种情况下,订阅者需要使用调度器类安排 UI 线程上的更新。提供Prism库的用户可以通过允许订阅者自动接收 UI 线程上的事件来提供帮助。订阅者在订阅期间表示此内容,如下表示示例所示。PubSubEvent

public class MainPageViewModel { 

public MainPageViewModel(IEventAggregator ea) {
ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);
}

void ShowNews(string companySymbol) { //implement logic } }

以下选项可用于:ThreadOption

  • PublisherThread: 使用此设置在发布商的线程上接收事件。这是默认设置。
  • BackgroundThread: 使用此设置在 .NET 框架线程池线程上异步接收事件。
  • UIThread: 使用此设置在 UI 线程上接收事件。

2.5 订阅过滤

  订阅者可能不需要处理已发布事件的每个实例。在这些情况下,订阅者可以使用过滤参数。过滤参数属于类型,是当事件发布时执行的委托,以确定已发布事件的有效载荷是否与调用用户回调所需的一组标准相匹配。如果有效载荷不符合指定标准,则未执行用户回拨。System.Predicate<TPayLoad>。

  通常,此筛选器以 lambda 表示形式提供,如下表示示例所示。

public class MainPageViewModel { 

public MainPageViewModel(IEventAggregator ea) {
TickerSymbolSelectedEvent tickerEvent = ea.GetEvent<TickerSymbolSelectedEvent>();
tickerEvent.Subscribe(ShowNews, ThreadOption.UIThread, false, companySymbol => companySymbol == "STOCK0");
}

void ShowNews(string companySymbol) { //implement logic } }

2.6 使用强参考订阅

  如果您在短时间内提出多个事件,并且注意到了对绩效的关注,则可能需要订阅具有强烈委托引用的订阅。如果这样做,则在处置订阅者时,您需要手动取消订阅。默认情况下,对订阅者处理程序和订阅过滤器保持弱代表引用。这意味着保留的引用不会阻止用户收集垃圾。使用弱委托参考可减轻订阅者取消订阅的需要,并允许适当的垃圾收集。PubSubEventPubSubEvent但是,保持此弱代表引用的速度比相应的强参考要慢。对于大多数应用程序,此性能不会明显,但如果您的应用程序在短时间内发布大量事件,您可能需要使用与 PubSubEvent 的强参考。如果您确实使用了强大的委托参考,则您的订阅者应取消订阅,以便在不再使用订阅对象时能够正确收集订阅对象。

要具有很强的参考性订阅,请使用方法上的参数,如下表示例所示。keepSubscriberReferenceAliveSubscribe

public class MainPageViewModel {
public MainPageViewModel(IEventAggregator ea) {
bool keepSubscriberReferenceAlive = true;
TickerSymbolSelectedEvent tickerEvent = ea.GetEvent<TickerSymbolSelectedEvent>();
tickerEvent.Subscribe(ShowNews, ThreadOption.UIThread, keepSubscriberReferenceAlive, companySymbol => companySymbol == "STOCK0");
}
void ShowNews(string companySymbol) { //implement logic } }
参数类型:keepSubscriberReferenceAlivebool
  • 设置为 "事件实例"时,会强烈引用订阅者实例,从而不允许其收集垃圾。有关如何取消订阅的信息,请参阅此主题稍后从事件中取消订阅的部分。true
  • 设置为(此参数省略时的默认值)时,该事件对订阅者实例的引用较弱,从而允许垃圾收集器在没有其他引用的情况下处置订阅者实例。收集订阅者实例后,事件会自动取消订阅。false

2.7 取消订阅活动

  如果您的订阅者不再希望接收事件,您可以使用订阅者处理程序取消订阅,也可以使用订阅令牌取消订阅。以下代码示例显示如何直接取消订阅到处理程序。

public class MainPageViewModel { 
TickerSymbolSelectedEvent _event;

public MainPageViewModel(IEventAggregator ea) {
_event = ea.GetEvent<TickerSymbolSelectedEvent>();
_event.Subscribe(ShowNews);
}

void Unsubscribe() {
_event.Unsubscribe(ShowNews);
}

void ShowNews(string companySymbol) { //implement logic } }
以下代码示例显示了如何使用订阅令牌取消订阅。该令牌以该方法的回报值提供。Subscribe
public class MainPageViewModel { 
TickerSymbolSelectedEvent _event;
SubscriptionToken _token;

public MainPageViewModel(IEventAggregator ea) {
_event = ea.GetEvent<TickerSymbolSelectedEvent>();
_token = _event.Subscribe(ShowNews);
}

void Unsubscribe() {

_event.Unsubscribe(_token);
}

void ShowNews(string companySymbol) { //implement logic } }

原文地址:https://www.cnblogs.com/minhost/p/15158279.html