• Prism 5.事件聚合


    Prism 5.事件聚合

    Prism提供了一种基于事件聚合服务机制,允许组件之间进行发布订阅,不相互引用也能进行通讯

    EventAggregator提供了多播发布订阅功能,多个发起者可以发布同一事件,多个订阅者也可以相应同一事件。

    IEventAggregator接口提供了容器类服务实现发布订阅,他会在第一次连接时去实例化,所以不用去担心他的实例化

    而真正工作中是用PubSubEvent类去实现发布订阅。

    创建一个事件

    public class TickerSymbolSelectedEvent : PubSubEvent<string>{}
    

    发布事件

    发布者通过在EventAggregator中检索事件然后发起,首先在你的构造函数中需要有一个EventAggregator,你可以通过DI去实例化它

    public class MainPageViewModel
    {
        IEventAggregator _eventAggregator;
        public MainPageViewModel(IEventAggregator ea)
        {
            _eventAggregator = ea;
        }
    }
    

    然后发布事件

    _eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish("STOCK0");
    

    订阅事件

    订阅者通过在PubSubEvent类中用Subscribe的重载方法去注册事件

    public class MainPageViewModel
    {
        public MainPageViewModel(IEventAggregator ea)
        {
            ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews);
        }
    
        void ShowNews(string companySymbol)
        {
            //implement logic
        }
    }
    

    这里有几条原则可以让你找到最适合你的订阅事件的方式:

    1 当事件接收后,你要更新UI界面的元素,你要在UI线程订阅接收事件

    2 如果你是想过滤事件,当订阅时要提供一个过滤委托

    3 用强类型的委托订阅事件并手动取消订阅,这将大大提高性能

    4 一条都没中你就用默认的就行了

    在UI线程订阅事件

    有时候订阅者在接收事件后腰更新UI界面上元素,然后在WPF中,只有UI线程才能更新界面元素,

    但是,一般来说,订阅者是在发布者的线程里接收事件,

    如果发布者就是UI线程,那就莫问题啊,

    如果发布者是在后台线程,订阅者就不能直接的更新UI了,需要调度Dispatcher去更新UI线程。

    PubSubEvent提供了一个自动的方式帮助订阅者在UI线程更新界面元素

    public class MainPageViewModel
    {
        public MainPageViewModel(IEventAggregator ea)
        {
            ea.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);
        }
    
        void ShowNews(string companySymbol)
        {
            //implement logic
        }
    }
    

    ThreadOption有三类:

    1 PublisherThread

    2 BackgroundThread,这是一个线程池线程

    3 UIThread

    警告:EventAggregator必须得是UI线程定义的才可以使用自动UI线程更新界面元素

    订阅过滤

    订阅者不必处理发布者的所有事件,所以订阅者得有一个过滤器来筛选

    这个过滤器是针对类型的

    System.Predicate<T>
    
    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
        }
    }
    

    使用强类型订阅

    对时间有大量事件的话,如果你对性能有要求,你可以使用强引用,如果你选择使用强引用,当你想释放订阅者的时候你就必须手动取消订阅

    默认情况下,PubSubEvent维持着一种对于定于订阅处理和过滤引用的弱委托,使用弱委托引用可以使订阅者不必取消订阅,并可以进行正确的垃圾回收。

    但是弱委托比强委托要慢,如果你使用强委托,则订阅者应取消订阅以确保能垃圾回收。

    Subscribe方法内使用keepSubscriberReferenceAlive参数进行强委托

    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
        }
    }
    

    keepSubscriberReferenceAlive

    true:不会自动进行垃圾回收,应该手动取消订阅

    false:默认值,没有引用的话就会自动垃圾回收并自动取消订阅

    取消订阅事件

    两种方式:

    1 取消订阅处理

    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
        }
    }
    

    2 通过Subscribe方法返回值-订阅token来取消订阅

    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
        }
    }
    
  • 相关阅读:
    MySQL和hive对比表结构脚本
    服务器端口3次不通报警
    CentOS 7 安装以及配置桌面环境
    MySQL修改参数不重启生效
    linux mysql 5.7.17 编译安装小记
    react脚手架应用以及iview安装
    weex具体安装教程
    npm教程2——脚手架原理及jQuery和bootstrap引入
    npm具体安装教程
    JAVA学习总结(六)
  • 原文地址:https://www.cnblogs.com/swobble/p/12809970.html
Copyright © 2020-2023  润新知