2014-08-29 3 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

+0

Aron, в одной строке возникает вопрос: «У каждого экземпляра любого класса есть своя копия обработчика событий, реализованного внутри класса» –

+0

Я могу прочитать ваше название. Я не могу это понять. Вы пытались написать какой-нибудь тестовый код, чтобы узнать, какое поведение вы получаете? – Aron

ответ

1

Я не уверен, что полностью подчиняюсь вашему вопросу ... но, возможно, это помогает.

У вас есть экземпляр класса 1, и он вызывает EventA. Экземпляр класса 1 действительно контролирует EventA. EventA может иметь обработчиков в любом количестве заинтересованных классов, но есть еще только один Class1 и один поднятие EventA. Делегат, вызываемый при возникновении события, не является статическим, поэтому он является его собственной копией (в любом классе), но помните, что параметры, определенные делегатом, могут быть разделены или класс, который вызывает событие, также может быть разделен как все происходят от поднятия класса 1.

+0

Спасибо D. Похоже, у меня есть экземпляр класса 1, у которого есть обработчик событий (он не вызывает никакого события). Затем я создаю 2 экземпляра Class1, которые являются экземплярами1 и экземпляром2. Оба экземпляра должны иметь свои собственные копии членов Class1 (свойства/методы и этот обработчик событий). Похоже, что хотя у них есть свои собственные копии остальных членов, eventhadler разделяется между двумя экземплярами, хотя обработчик событий не является ни статичным, либо не использует какой-либо статический объект. Это ожидаемое поведение? –

+0

У меня нет статического/совместно используемого элемента в Class1, ни один из них не является статичным. –

+0

У вас может быть несколько экземпляров вашего класса (VideoPlayer), обрабатывающих RtpFrameChanged на клиенте, но все ли они обрабатывают событие для одного и того же экземпляра клиента? – Jay

Смежные вопросы