仅是如何保证事件订阅一次 [英] How to ensure an event is only subscribed to once

查看:93
本文介绍了仅是如何保证事件订阅一次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想确保我只在一个特定的类认购一次上的一个实例的事件。

I would like to ensure that I only subscribe once in a particular class for an event on an instance.

例如我想能够做到以下几点:

For example I would like to be able to do the following:

if (*not already subscribed*)
{
    member.Event += new MemeberClass.Delegate(handler);
}

我如何去实施这样的后卫?

How would I go about implementing such a guard?

推荐答案

如果你正在谈论您拥有访问源,然后一类的事件,你可以放置后卫事件定义。

If you are talking about an event on a class that you have access to the source for then you could place the guard in the event definition.

private bool _eventHasSubscribers = false;
private EventHandler<MyDelegateType> _myEvent;

public event EventHandler<MyDelegateType> MyEvent
{
   add 
   {
      if (_myEvent == null)
      {
         _myEvent += value;
      }
   }
   remove
   {
      _myEvent -= value;
   }
}

这将确保只有一个用户可以订阅的事件上,提供事件的类的实例。

That would ensure that only one subscriber can subscribe to the event on this instance of the class that provides the event.

修改请查看为什么上面code是一个坏主意的意见和不是线程安全的。

EDIT please see comments about why the above code is a bad idea and not thread safe.

如果你的问题是,客户端的单个实例订阅超过一次(你需要多个用户),然后在客户端code将需要来处理。因此,替换

If your problem is that a single instance of the client is subscribing more than once (and you need multiple subscribers) then the client code is going to need to handle that. So replace

不是已经订阅

与当您订阅该事件的第一次时设置客户端类的布尔成员。

with a bool member of the client class that gets set when you subscribe for the event the first time.

修改(后接受):基于从@Glen T(问题的提交者)在code为接受的解决方案,他与在客户端类去注释:

Edit (after accepted): Based on the comment from @Glen T (the submitter of the question) the code for the accepted solution he went with is in the client class:

if (alreadySubscribedFlag)
{
    member.Event += new MemeberClass.Delegate(handler);
}

在哪里alreadySubscribedFlag是在第一次跟踪订阅的特定事件的客户端类的成员变量。
人们希望在第一code片段在这里,请走@符文的评论笔记 - 它不是要改变以非明显的方式订阅事件的行为是个好主意。

Where alreadySubscribedFlag is a member variable in the client class that tracks first subscription to the specific event. People looking at the first code snippet here, please take note of @Rune's comment - it is not a good idea to change the behavior of subscribing to an event in a non-obvious way.

修改31/7/2009:请看到@Sam藏红花的意见。正如我已经说过和Sam同意在这里psented第一种方法$ P $不要修改事件订阅的行为合理的方式。类的消费者需要了解其内部实现以了解其行为。不是很好。

@Sam藏红花还评论关于线程安全。我假设他是指可能的竞争条件,其中两个用户(接近)同时尝试以认购,他们可能都结束了订阅。锁可以用来改善这一点。如果您计划的方式来改变事件订阅作品那么我建议你了解如何使订阅添加/删除属性线程安全

EDIT 31/7/2009: Please see comments from @Sam Saffron. As I already stated and Sam agrees the first method presented here is not a sensible way to modify the behavior of the event subscription. The consumers of the class need to know about its internal implementation to understand its behavior. Not very nice.
@Sam Saffron also comments about thread safety. I'm assuming that he is referring to the possible race condition where two subscribers (close to) simultaneously attempt to subscribe and they may both end up subscribing. A lock could be used to improve this. If you are planning to change the way event subscription works then I advise that you read about how to make the subscription add/remove properties thread safe.

这篇关于仅是如何保证事件订阅一次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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