Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Prism EventAggregator订阅引用自身以取消订阅的委托_C#_Delegates_Prism_Eventaggregator - Fatal编程技术网

C# Prism EventAggregator订阅引用自身以取消订阅的委托

C# Prism EventAggregator订阅引用自身以取消订阅的委托,c#,delegates,prism,eventaggregator,C#,Delegates,Prism,Eventaggregator,是否可以这样做: EventHandler handler = null; handler = (s, args) => { DoStuff(); something.SomeEvent -= handler; }; something.SomeEvent += handler; 使用Prism的事件聚合器? 即 动作订阅者=null; 订户=()=> { DoStuff(); EventAggregator.GetEvent().Unsubscribe(订阅者); };

是否可以这样做:

EventHandler handler = null;
handler = (s, args) =>
{
    DoStuff();
    something.SomeEvent -= handler;
};
something.SomeEvent += handler;
使用Prism的事件聚合器? 即

动作订阅者=null;
订户=()=>
{
DoStuff();
EventAggregator.GetEvent().Unsubscribe(订阅者);
};
EventAggregator.GetEvent().Subscribe(订阅服务器);

是的,这也适用于Prism的事件聚合器。这一切归结为比较两个示例中的代理是否相等。在anyonymous方法中引用委托不是特定于事件聚合器的

但是,您应该注意,在使用匿名方法进行此类一次性事件处理时,由于您保持委托实例
处理程序
订户
,因此在更复杂的场景中,订阅和取消订阅匿名方法可能非常困难。为了理解匿名方法的委托比较是如何工作的,您应该看看这两个问题

作为使用匿名方法的替代方法,您可以使用实例方法,也可以使用C#7.0中引入的方法,如下面的示例所示

private void AddEventHandler()
{
   // Local method to replace your anonymous method
   void DoStuffAndUnsubscribe()
   {
      DoStuff();
      eventAggregator.GetEvent<SomeEvent>().Unsubscribe(DoStuffAndUnsubscribe);
   }

   eventAggregator.GetEvent<SomeEvent>().Subscribe(DoStuffAndUnsubscribe);
}

Subscribe
返回一个订阅对象,您可以通过该对象取消订阅:

IDisposable subscription = null;
subscription = eventAggregator.GetEvent<SomeEvent>().Subscribe( () =>
                                                                {
                                                                    // do something
                                                                    subscription.Dispose();
                                                                } );
IDisposable订阅=null;
订阅=eventAggregator.GetEvent().Subscribe(()=>
{
//做点什么
subscription.Dispose();
} );

这太复杂了,您可以将订阅(从
Subscribe
返回的值)处理为取消订阅。谢谢,我想到了订阅令牌,但没有在lambda中捕获它们。我注意到本地函数只能从包含方法访问值类型,而不能访问引用类型。这就是它的工作原理,还是我做错了什么?@JamesDePaola我已经测试了上述所有方法,以确保它们工作正常。局部函数可以捕获实例状态、方法参数或局部变量,不应仅限于值类型。只要试着创建一个本地
对象
并在本地方法中引用它,就可以了。@这就是我使用的:
intx=1;对象y=新文本框();IDisposable subscriptionToken=null;subscriptionToken=this.EventAggregator.GetEvent().Subscribe((args)=>{//x=6;//y=new CheckBox();System.Diagnostics.Debugger.Break();//subscriptionToken.Dispose();})一旦我取消注释这些行中的任何一行,即使只是“x=6;”,匿名方法也不会被调用;但只要在匿名方法之外声明的对象在该方法内,就永远不会调用该方法。所以我不知道为什么它对我不起作用。我甚至把你的代码复制到我的代码里。在我注释掉引用“subscription”的行之前,不会调用匿名方法
IDisposable subscriptionToken = null;
subscriptionToken = eventAggregator.GetEvent<SomeEvent>().Subscribe(() =>
{
    DoStuff();
    subscriptionToken.Dispose();
});
IDisposable subscription = null;
subscription = eventAggregator.GetEvent<SomeEvent>().Subscribe( () =>
                                                                {
                                                                    // do something
                                                                    subscription.Dispose();
                                                                } );