1

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

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

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

在类库接口中有这样的代码:

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 被调用时,调试器说Subscriptions = 1(所以它知道订阅已经完成,所以我似乎没有 2 个不同的 IEventAggregator 实例。)

但是 OnRandomThingDone 在 Publish 之后永远不会被调用。

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

4

3 回答 3

7

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

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

如果您的订阅者随后成功接收到事件,则意味着包含 OnRandomThingDone 的类超出范围并在事件发布之前获得 GC。

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

于 2010-11-15T04:19:14.730 回答
1

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

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

有关这方面的更多信息,请参阅:第 9 章:在松散耦合组件之间进行通信部分订阅使用强引用

于 2012-01-07T09:52:25.927 回答
0

它与 GC 无关,因为一旦 Subsriber 附加了对它的引用,它就永远不会消失。真正的问题是由于无法访问OnRandomThingDone if 必须是公开的,即:

**public** void OnRandomThingDone(string obj)
{
    MessageBox.Show("Random Event Done With: " + obj);            
}
于 2010-12-04T07:39:14.737 回答