0

I am trying to hook up interface.MessageReceived to logger.LogReceivedMessage. If I add interface.MessageReceived += LogReceivedMessage; in logger's constructor, LogReceivedMessage is called as expected.

However, if I move the hookup to some other place in logger, LogReceivedMessage is never called.

All other hookups to interface.MessageReceived use += and not =, so that's not the problem.

I used the Watch window and "Make Object ID" option in Visual Studio to verify that the code has the same instance of interface both places. It does. However, interface.MessageReceived has a different object in the constructor than the other places in the code. In fact, it seems to change every time something is hooked up to it. I'm not sure if that is expected or not.

Does anyone have any ideas why I can only hook up the handler in the constructor?

Edit: I've gotten it working, but I'm not sure why it works. Original code in the interface class:

public event Action<Message> MessageReceived;
busClient.MessageReceived += MessageReceived

I changed it to:

public event Action<Message> intermediateMessageReceived;
public event Action<Message> MessageReceived;
busClient.MessageReceived += intermediateMessageReceived;

public void intermediateMessageReceived(Message m)
{
   MessageReceived(m);
}

Without posting all the code to the entire project, does anyone have any idea why this behaves differently?

4

1 回答 1

1

我想分享我对 C# 中与此问题相关的事件的了解。我们不明白事件是如何运作的,这导致了我们的问题。

当您将事件 B 订阅到事件 A 时,调用事件 A 只会调用在事件 B 订阅 A 时订阅事件 B 的内容。如果 B 的订阅者发生更改,则调用事件 A 时不会反映该更改。

以下代码演示:

namespace EventDemonstrator
{
   class Program
   {
      class BottomLayer
      {
         public event System.Action<string> Event;
        public void callEvent() { Event("bottom"); }
      }
      class MiddleLayer
      {
         public void HookUpEvent(BottomLayer bl) { bl.Event += this.Event; }
         public event System.Action<string> Event;
      }
      class TopLayer
      {
         public void TopLayerHandler(string s)
         {
            System.Console.Write(string.Format(" {0} top\n", s));
         }
      }

      static void HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top)
      {
         middle.HookUpEvent(bottom);
         middle.Event += top.TopLayerHandler;
         try {bottom.callEvent(); }
         catch (System.NullReferenceException) { System.Console.Write("HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom: Event was null\n"); }
      }

      static void HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom(BottomLayer bottom, MiddleLayer middle, TopLayer top)
      {
         middle.Event += top.TopLayerHandler;
         middle.HookUpEvent(bottom);
         System.Console.Write("HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom:");
         bottom.callEvent();
      }

      static void Main(string[] args)
      {
         HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom(new BottomLayer(), new MiddleLayer(), new TopLayer());
         HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom(new BottomLayer(), new MiddleLayer(), new TopLayer());
      }
   }
}

输出:

HookBottomToMiddle_ThenMiddleToTop_ThenCallBottom: Event was null
HookMiddleToTop_ThenBottomToMiddle_ThenCallBottom: bottom top
于 2013-09-16T15:30:59.190 回答