EventAggregator无法跨模块访问

时间:2010-11-15 03:51:32

标签: c# wpf unity-container prism eventaggregator

我试图让我的IEventAggregator允许我在一个模块中发布和事件并在另一个模块中捕获它。我在单个模块/项目中尝试了下面的代码,效果很好。只有当我有一个模块/项目发布事件而另一个订阅它时它才会失败。

我已经通过统一将IEventAggregator注入两个模块。

我有3个项目,其中两个有模块(称为A和B),一个只是一个普通的类库(称之为接口)

在类库 Interfaces 中有以下代码:

public class RandomTestEvent : CompositePresentationEvent<string>
{
}

在模块 A 中,按钮单击命令中存在此代码(这实际上位于项目中的视图模型中):

var evt2 = _eventAggregator.GetEvent<RandomTestEvent>();
evt2.Publish("Testing");

在模块 B 中有以下代码:

    public void Initialize()
    {
        var evt2 = _eventAggregator.GetEvent<RandomTestEvent>();
        evt2.Subscribe(OnRandomThingDone);
    }

    private void OnRandomThingDone(string obj)
    {
        MessageBox.Show("Random Event Done With: " + obj);            
    }

我可以追踪,我看到订阅被调用。当我查看Publish geting时调用者说Subscriptions = 1(因此它知道订阅已经完成,所以我似乎没有2个不同的IEventAggregator实例。)

但OnRandomThingDone永远不会在发布后调用。

任何想法为什么? (我需要发布更多代码吗?如果有,请告诉我。)

3 个答案:

答案 0 :(得分:7)

真的随机猜测 - 您的订阅者在事件发布之前获得了GC'd - 因为Prism的CompositePresentationEvent的默认行为是使用WeakReferences来保留订阅者目标引用。

所以...尝试调用Subscribe重载,它允许你指定keepSubscriberReferenceAlive并传入true。

如果您的订阅者成功收到该事件,则表示您的包含OnRandomThingDone的类超出范围并在事件发布之前获得GC。

随机API参考: http://msdn.microsoft.com/en-us/library/ff921122(PandP.20).aspx

答案 1 :(得分:1)

实际上grimcoder是正确的,弱引用需要一个公共Action方法。 利用周参考可以减轻编码人员取消订阅事件的速度,这由GC管理。

然而,您可以通过将true传递给keepSubscriberReferenceAlive来使用强引用,如果在短时间内调用大量事件,也可以加速您的程序。

有关详细信息,请参阅:Chapter 9: Communicating Between Loosely Coupled Components部分 使用强引用订阅

答案 2 :(得分:0)

它与GC无关,因为一旦订阅者附加引用它永远不会死亡。 真正的问题是由于OnRandomThingDone无法访问 如果必须公开,即:

**public** void OnRandomThingDone(string obj)
{
    MessageBox.Show("Random Event Done With: " + obj);            
}