【问题标题】:Log who subscribs to a event记录谁订阅了一个事件
【发布时间】:2011-07-19 13:56:20
【问题描述】:

在 C# 中是否可以检索谁正在订阅事件?

例子

class MyClass
{
  public string Name { get; set; } 
}

class Syncronizer
{
  public delegate void SynchronizatonEventHandler(MyClass myClass);
  public event SynchronizatonEventHandler OnSyncFinished;
}

如果我有类似的东西,我是否可以查看/使用 myClass.Name 字符串并在订阅事件时使用它来记录?

我想要完成的是我想记录每个订阅和取消订阅我的 Syncronizer 类。

【问题讨论】:

    标签: c# .net


    【解决方案1】:

    您可以执行以下操作:

    class MyClass
    {
        public string Name { get; set; }
    }
    
    class Syncronizer
    {
        public delegate void SynchronizatonEventHandler(MyClass myClass);
        internal event SynchronizatonEventHandler _onSyncFinished;
    
        public event SynchronizatonEventHandler OnSyncFinished
        {
            add
            {
                // Perform some code before the subscription.
                // Add the event.
                _onSyncFinished += value;
                // Perform some code after the subscription;
            }
            remove
            {
                // Perform some code before the subscription.
                // Remove the event.
                _onSyncFinished -= value;
                // Peroform some code after the subscription.
            }
        }
    }
    

    【讨论】:

    • 这段代码会导致 StackOverflowException... 除了事件之外,您还需要创建一个 EventHandler 类型的字段,并在事件访问器中操作该字段
    • 我认为这很清楚。我用一个完整的解决方案改变了答案。
    【解决方案2】:

    这是一个工作示例:

    class Syncronizer
    {
        public delegate void SynchronizatonEventHandler(MyClass myClass);
        private event SynchronizatonEventHandler onSyncFinished;
        public event SynchronizatonEventHandler OnSyncFinished
        {
            add
            {
                var method = new StackTrace().GetFrame(1).GetMethod();
                Console.WriteLine("{0}.{1} subscribing", method.ReflectedType.Name, method.Name);
                onSyncFinished += value;
            }
            remove
            {
                var method = new StackTrace().GetFrame(1).GetMethod();
                Console.WriteLine("{0}.{1} unsubscribing", method.ReflectedType.Name, method.Name);
                onSyncFinished -= value;
            }
        }
    }
    

    请注意,您不能记录 myClass.Name,因为添加和删除过程中不存在该名称。我让它记录(到 Console.WriteLine)订阅事件的类和方法,我认为,这就是你所追求的。

    【讨论】:

      【解决方案3】:

      您需要使用自己的accessors 创建显式事件:

      public event SynchronizatonEventHandler OnSyncFinished {
          add { ... }
          remove { ... }
      }
      

      addremove 采用 value 参数,其中包含要从事件中删除或添加到事件中的委托实例。
      出于记录目的,您可以获得实例的MethodTarget 属性。

      【讨论】:

        【解决方案4】:

        某事。这样应该可以解决您的问题:

        private event SynchronizatonEventHandler m_OnSyncFinished;
        
        public event SynchronizatonEventHandler OnSyncFinished
        {
          add
          {
            // Custom code could be added here...
            m_OnSyncFinished += value;
          }
          remove
          {
            // Custom code could be added here...
            m_OnSyncFinished -= value;
          }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-07-31
          • 1970-01-01
          • 2021-04-03
          • 1970-01-01
          • 1970-01-01
          • 2023-03-07
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多