带有棱镜的事件订阅提供方法访问异常 [英] Event subscription with prism giving methodaccess exception

查看:48
本文介绍了带有棱镜的事件订阅提供方法访问异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在视图模型中订阅了一个事件.事件订阅是在通过 unity 创建的视图模型的构造函数中完成的.

I have an event that I am subscribing to in a View Model. The event subscription is done in the constructor of the view model which is created via unity.

我发现如果我订阅为:

showViewAEvent.Subscribe(ShowViewAHasBeenRequested) 或 showViewAEvent.Subscribe(ShowViewAHasBeenRequested, False) 我收到以下错误:

showViewAEvent.Subscribe(ShowViewAHasBeenRequested) or showViewAEvent.Subscribe(ShowViewAHasBeenRequested, False) I get the following error:

       // {System.MethodAccessException: ModuleA.Views.ModuleAViewModel.ShowViewAHasBeenRequested(Boolean)
       //at System.Delegate.BindToMethodInfo(Object target, RuntimeMethodHandle method, RuntimeTypeHandle methodType, DelegateBindingFlags flags)
       //at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
       //at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method)
       //at Microsoft.Practices.Composite.Events.DelegateReference.TryGetDelegate()
       //at Microsoft.Practices.Composite.Events.DelegateReference.get_Target()
       //at Microsoft.Practices.Composite.Events.EventSubscription`1..ctor(IDelegateReference actionReference, IDelegateReference filterReference)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive, Predicate`1 filter)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, ThreadOption threadOption, Boolean keepSubscriberReferenceAlive)
       //at Microsoft.Practices.Composite.Presentation.Events.CompositePresentationEvent`1.Subscribe(Action`1 action, Boolean keepSubscriberReferenceAlive)
       //at ModuleA.Views.ModuleAViewModel..ctor(IEventAggregator eventAggregator, IRegionManager regionManager)
       //at BuildUp_ModuleA.Views.ModuleAViewModel(IBuilderContext )
       //at Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlan.BuildUp(IBuilderContext context)
       //at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context)
       //at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context)}

但是,如果我在事件订阅上将标志设置为 true,则不会收到错误消息.

But, if I set the flag to true on the event subscription, I do not get the error.

由于我是 Prism 的新手,我仍在努力确定我是否在正确的位置创建订阅.

As I am new to prism, I am still trying to work out if I am creating the subscription in the right place.

京东.

推荐答案

这是一个完整记录的已知问题:

This is a known issue fully documented here :

http://compositewpf.codeplex.com/WorkItem/View.aspx?WorkItemId=4925

CompositePresentationEvent<>.Subscribe() 中的错误防止弱事件引用标题是必需的

Bug in CompositePresentationEvent<>.Subscribe() prevents weak event references Title is required

描述 需要描述概述:

此类的 Subscribe() 方法被记录为默认创建 WeakReferences,或者在包含该参数的重载中指定为 keepSubscriberReferenceAlive=false 时.

The Subscribe() method of this class is documented as creating WeakReferences by default or when specified as keepSubscriberReferenceAlive=false in the overloads that include that parameter.

详情:

只有在提供过滤器委托时才能正确观察到此行为.在所有其他情况下(以及 Subscribe() 方法的所有重载),都会创建强引用 - 无论记录的默认值如何,也无论是否为 keepSubscriberReferenceAlive 参数提供了任何值.

This behavior is only correctly observed when a filter delegate is supplied. In all other cases (and all overloads of the Subscribe() method), a strong reference is created - regardless of the documented default and regardless of any supplied value for the keepSubscriberReferenceAlive parameter.

可以在此方法的以下重载中找到此错误的来源:

The source of this bug can be found in the following overload of this method:

CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate filter)

CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive, Predicate filter)

在此方法中,检查过滤器"参数.如果过滤器不为空,则处理继续正确.但是,如果此参数为 null,则会创建一个新的传递委托(始终返回 true)并将其用于过滤器.错误在于,从此传递委托创建的 DelegateReference 对象具有硬编码为值true"的 keepReferenceAlive 参数.此值不应硬编码,而应传递传入参数 keepSubscriberReferenceAlive.

In this method, the "filter" parameter is inspected. If the filter is not null, then processing continues correctly. However, if this parameter is null then a new pass-through delegate (always returns true) is created and used for the filter. The bug is that the DelegateReference object that is created from this pass-through delegate has the keepReferenceAlive parameter hard-coded to the value "true". This value should not be hard-coded, and instead the incoming parameter keepSubscriberReferenceAlive should be passed.

解决方法:

此问题有一个简单的解决方法.注册订阅时,您应该始终使用上述详细重载,并始终提供过滤器委托.永远不要为过滤器参数传递null".如果不应过滤订阅,则应在需要弱事件引用时使用传递过滤器委托(典型情况):

There is a simple workaround for this issue. When registering a subscription, you should always use the verbose overload stated above, and always supply a filter delegate. Never pass "null" for the filter parameter. If the subscription should not be filtered, then a pass-through filter delegate should be used when a weak event reference is desired (the typical scenario):

EventAggregator.GetEvent().Subscribe(MyHandler, ThreadOption.PublisherThread, false, (dummy) => true);

EventAggregator.GetEvent().Subscribe(MyHandler, ThreadOption.PublisherThread, false, (dummy) => true);

对于以下缩写重载没有解决方法,并且在修补底层错误之前不应使用这些:

There is NO workaround for the following abbreviated overloads, and these should not be used until the underlying bug has been patched:

CompositePresentationEvent.Subscribe(Action action)CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption)CompositePresentationEvent.Subscribe(Action action, bool keepSubscriberReferenceAlive)CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)

CompositePresentationEvent.Subscribe(Action action) CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption) CompositePresentationEvent.Subscribe(Action action, bool keepSubscriberReferenceAlive) CompositePresentationEvent.Subscribe(Action action, ThreadOption threadOption, bool keepSubscriberReferenceAlive)

这篇关于带有棱镜的事件订阅提供方法访问异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆