如何确保一个事件只订阅一次 [英] How to ensure an event is only subscribed to once

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

问题描述

我想确保我只在特定类中为实例上的事件订阅一次.

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.

编辑请查看有关为什么上述代码是一个坏主意并且不是线程安全的评论.

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

如果您的问题是客户端的单个实例订阅了多次(并且您需要多个订阅者),那么客户端代码将需要处理该问题.所以替换

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

尚未订阅

客户端类的 bool 成员在您第一次订阅事件时设置.

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

编辑(接受后):根据@Glen T(问题的提交者)的评论,他采用的已接受解决方案的代码在客户端类中:

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 是客户端类中的成员变量,用于跟踪对特定事件的首次订阅.在这里查看第一个代码片段的人,请注意@Rune 的评论 - 以不明显的方式更改订阅事件的行为不是一个好主意.

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.

EDIT 31/7/2009:请参阅@Sam Saffron 的评论.正如我已经说过的,Sam 同意这里介绍的第一种方法不是修改事件订阅行为的明智方法.类的使用者需要了解其内部实现以了解其行为.不是很好.
@Sam Saffron 还评论了线程安全.我假设他指的是可能的竞争条件,即两个订阅者(接近)同时尝试订阅并且他们最终都可能订阅.可以使用锁来改善这一点.如果您打算更改事件订阅的工作方式,那么我建议您阅读有关如何使订阅添加/删除属性线程安全.

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天全站免登陆