2014-08-29 76 views
0

我理解發布者 - 訂閱者模式,但我的問題是如果類的每個對象都有它自己的事件處理副本。我搜索了SE,但大多數問題與事件訂閱簽名相關,如C#: Difference between ' += anEvent' and ' += new EventHandler(anEvent)'是否只有一個事件處理程序的所有對象的副本

我有一個類:

  namespace VideoClient 
      { 
       class VideoPlayer 
       { 
        Thread ClientThreadProc; 
        [DllImport("gdi32.dll", CharSet = CharSet.Auto)] 
        public static extern Int32 DeleteObject(IntPtr hGDIObj); 
        RtspClient client; 
        IntPtr hBitmap; 
        public string cameranameTemp; 

        public delegate void Source(System.Windows.Media.Imaging.BitmapSource source, Bitmap Image); 
        public event Source SourceHandler; 

        public VideoPlayer(string URL, string Username, string Password) 
        { 
         client = new RtspClient(URL); 
         client.Credential = new System.Net.NetworkCredential(Username, Password); 
         client.AuthenticationScheme = System.Net.AuthenticationSchemes.Basic; 


        } 

        public void Play() 
        { 
         client.OnConnect += (sender, args) => 
         { 
          sender.OnPlay += (sender1, args1) => 
          { 
           sender1.Client.FrameChangedEventsEnabled = true; 
           sender1.Client.RtpFrameChanged += Client_RtpFrameChanged; 
           sender1.Client.SetReceiveBufferSize(1024 * 1024); 
          }; 
          try 
          { 
           sender.StartListening(); 
          } 
          catch (Exception ex) 
          { 
           //SignalLost = true; 
           //IsStreaming = false; 
          } 
         }; 

         client.OnDisconnect += (sender, args) => 
         { 
          sender.Client.Disconnect(); 
          sender.Client.Dispose(); 
          sender.Disconnect(); 
          sender.Dispose(); 
         }; 

         ClientThreadProc = new Thread(client.Connect); 
         ClientThreadProc.IsBackground = true; 
         ClientThreadProc.Start(); 
        } 

        public void Stop() 
        { 
         if (ClientThreadProc != null) 
          ClientThreadProc.Abort(); 
         client.StopListening(); 
        } 

        System.Windows.Media.Imaging.BitmapSource ConvertImage(System.Drawing.Bitmap bmp) 
        { 
         if (bmp == null) 
         { 
          return null; 
         } 
         hBitmap = bmp.GetHbitmap(); 
         System.Windows.Media.Imaging.BitmapSource bs = 
          System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
           hBitmap, 
           IntPtr.Zero, 
           System.Windows.Int32Rect.Empty, 
           System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions()); 
         DeleteObject(hBitmap); 
         bmp.Dispose(); 
         return bs; 
        } 

        void Client_RtpFrameChanged(object sender, Media.Rtp.RtpFrame frame) 
        { 
         if (frame.Complete && frame.HasMarker && frame.Count > 1) 
         { 
          try 
          { 
           string temp = this.cameranameTemp; bool bTemp = client.Connected; 
           Application.Current.Dispatcher.Invoke 
           (() => 
           { 
            if (frame.PayloadTypeByte == RFC2435Stream.RFC2435Frame.RtpJpegPayloadType && client.Listening) 
            { 
             var bitmap = (Bitmap)(new RFC2435Stream.RFC2435Frame(frame)); 
             if (bitmap != null) 
             { 
              Bitmap image = new Bitmap(bitmap); 
              SourceHandler(ConvertImage(bitmap), image); 
             } 

            } 
           }); 

          } 
          catch (Exception ex) 
          { Console.WriteLine(ex.Message.ToString()); } 

         } 

        } 

       } 
      } 

當我們初始化VideoPlayer類的實例,每個實例有其類的字段/方法/代表的副本等,但是否每個實例都有自己事件處理員的副本,在這種情況下; Client_RtpFrameChanged。我會這樣認爲,因爲它是一種訂閱事件的方法。但在運行應用程序時,此事件處理程序僅處理「最後」實例的事件,而之前初始化的所有實例似乎都沒有自己的事件處理程序副本。如果確實如此,那麼我怎樣才能讓每個實例擁有自己的eventhadler副本?

非常感謝。

+0

TLDR。請閱讀http://sscce.org然後重寫你的問題。 – Aron 2014-08-29 09:21:12

+0

阿龍,在一行中的問題是「每個類的每個實例都有自己的類裏面實現的事件處理器的副本」 – 2014-08-29 09:27:25

+0

我可以讀你的標題。我不能理解它。你有沒有試過寫一些測試代碼來看看你得到了什麼樣的行爲? – Aron 2014-08-29 09:33:58

回答

1

我不知道我完全按照你的問題......但也許這有助於。

你有一個Class1的實例,它會引發EventA。 Class1的實例確實在控制EventA。 EventA可以在任何數量的感興趣的類中都有處理程序,但仍然只有一個Class1和一個EventA。當引發事件時調用的委託不是靜態的,所以它是它自己的副本(在任何類上),但是請記住委託所定義的參數可能是共享的,或者引發事件的類也可以共享爲全部來自提高的Class1。

+0

謝謝D.它就像我有一個具有事件處理程序的Class1實例(它不會引發任何事件)。然後,我創建了兩個實例1和實例2的Class1實例。這兩個實例都應該擁有自己的Class1成員的副本(屬性/方法和此事件處理程序)。看起來雖然他們自己擁有其他成員的副本,但事件處理器在兩個實例之間共享,儘管事件處理器既不是靜態的也不使用任何靜態對象。這是預期的行爲? – 2014-08-29 13:04:44

+0

我在Class1中沒有任何靜態/共享成員,這個類也不是靜態的。 – 2014-08-29 13:06:30

+0

您可能有多個類的實例(VideoPlayer)處理客戶端上的RtpFrameChanged,但它們是否都處理相同客戶端實例的事件? – Jay 2014-08-29 14:41:28

相關問題