CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Jan 2007
    Posts
    102

    Using delegate for receiving data.

    Hello best programmers,

    I manged to get a socketconnection with another pc and I can receive data and read it. Now I want to call a function in the main when I receive data. I understand I need to use a delegate which encapsulates a a function (or a method) with the right signature...

    Because I'm a beginner in C# (I'm more a C/C++ programmer) I'm a bit confused where to define the delegate signature and where to attach the calling function. I made a seperate class which handles the network stuff (receiving and sending data) but in the receiving function I want to be able to call a function in the main. For example I want to see on the GUI if data is received. Finally I want to use also the event, because I'll use two threads!

    If somebody can give me some useful example's, tips, hints or links I'd appreciate that.

    Thank you.

  2. #2
    Join Date
    Oct 2007
    Posts
    11

    Re: Using delegate for receiving data.

    Hi,

    maybe the following code will give you an idea:

    Code:
      public class SocketDataEventArgs : EventArgs
      {
        byte[] _data;
    
        public SocketDataEventArgs(byte[] data)
        {
          _data = data;
        }
    
        // note: array typed get properties are usually considered bad style ...
        public byte[] Data
        {
          get
          {
            return _data;
          }
        }
      }
      
      
      public class Receiver
      {
        Socket _socket;
    
        public event EventHandler<SocketDataEventArgs> DataReceived;
    
        // init and connect code omitted
        
        void Receive()
        {
          // sync receive
          // exception and error handling omitted
          byte[] buffer = new byte[512];
    
          _socket.Receive(buffer);
    
          FireDataReceived(buffer);
        }
    
        void FireDataReceived(byte[] data)
        {
          EventHandler<SocketDataEventArgs> eventHandler = DataReceived;
    
          if(eventHandler != null)
            eventHandler(this, new SocketDataEventArgs(data));
        }
      }
    
    
      public class DataConsumer
      {
        Receiver _receiver;
    
        public DataConsumer(Receiver receiver)
        {
          _receiver = receiver;
    
          _receiver.DataReceived += OnDataReceived;      
        }
    
        
        void OnDataReceived(object sender, SocketDataEventArgs e)
        {
          // handle event
        }
      
      }
    As far as multithreaded programming/events and interaction with a GUI are
    concerned, that's a bit more complicated since Windows Forms controls may only be modified from the thread that created the controls.

    Take a look at the AsyncOperationManager and AsyncOperation classes, that might be a good start.


    Regards,

    Matthias.

  3. #3
    Join Date
    Jan 2007
    Posts
    102

    Re: Using delegate for receiving data.

    Hello MathiasD,

    First, thank you very much for your reply and your time to give me an example.
    I understand your example, and found out it's not so easy to implement an event. It takes some lines to write a simple event.

    One thing to make sure I understand well. If I fire an event from another thread than it's possible that a function in another thread can be called right?

    I want to fire an event when I receive some data from my socket, and I've programmed it such a way that when the receive event is fired, a function in the main thread will be called. This can be achieved by attaching a void MainThread.OnDataReceived(object sender, SocketDataEventArgs e) from the "Mainthread" to the Receiver object, right?

    This can be achieved without additional coding right? Your example should be enough to realize that, I think. Cause this should work like a PostMessage() in Visual C++ 6.0

  4. #4
    Join Date
    Oct 2007
    Posts
    11

    Re: Using delegate for receiving data.

    Hi,


    in the example I gave you, no context switches occur. The
    OnDataReceived function is triggered in the context of the
    thread that called the receive function.

    If you require your events to be delivered to a certain thread, take
    a look at AsyncOperationManager and AsyncOperation as I wrote before.

    Basically, you would need to create AsyncOperation object by calling
    AsyncOperationManager.CreateOperation(...) in the context of the
    thread you want to receive the events. Pass this AsyncOperation instance
    to all of your event sources. The FireDataReceived code using the AsyncOperation object looks something like this:

    Code:
      public class Receiver
      {
        Socket          _socket;
        AsyncOperation  _asyncOp;
    
        public event EventHandler<SocketDataEventArgs> DataReceived;
    
        // init and connect code omitted
        
        public Receiver(AsyncOperation asyncOp)
        {
          _asyncOp = asyncOp;
        }
    
        void Receive()
        {
          // sync receive
          // exception and error handling omitted
          byte[] buffer = new byte[512];
    
          _socket.Receive(buffer);
    
          FireDataReceived(buffer);
        }
    
        void FireDataReceived(byte[] data)
        {
          /* depending on how you do your buffering, you might want to copy the data to another buffer, not shown here  */ 
          _asyncOp.Post(new SendOrPostCallback(delegate(object state)
          {
            EventHandler<SocketDataEventArgs> eventHandler = DataReceived;
    
            if(eventHandler != null)
              eventHandler(this, new SocketDataEventArgs((byte[])state));
          }), data);
          
        }
      }

    Regards,

    Matthias.

  5. #5
    Join Date
    Jan 2007
    Posts
    102

    Re: Using delegate for receiving data.

    Thank you for your reply my friend,

    Than what is the purpose of an event?
    In that case I can throw away the event and use only a delegate to call a function.

    Isn't that when an event has fired that the OS puts the event in a queu and when it's fetched it calls the right function. Like the other buttons, mouseclicks etc... I thought when the main-thread is running it fetches the event and checks wether it's an event for his thread to process or not.

  6. #6
    Join Date
    Oct 2007
    Posts
    11

    Re: Using delegate for receiving data.

    Hi,


    you seem to confuse .net/c# events with event objects from the
    kernel space of the os. Those can be accessed via the EventWaitHandle class.



    Regards,

    Matthias.

  7. #7
    Join Date
    Jan 2007
    Posts
    102

    Re: Using delegate for receiving data.

    Matthias,

    Thank you very much for your value posts.
    I think I need to study some techniques in C# how to post a "message" from one thread to another thread.

    I also read that delegate and event actually behave the same. It's more the administrative things which differs, like adding more delegates in an event and some limitations on accesors etc..., all together these are finally encapsulated functionpointers.

    Anyway, thank you for your help my friend.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured