我试图让我的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永远不会在发布后调用。
任何想法为什么? (我需要发布更多代码吗?如果有,请告诉我。)
答案 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);
}