Asynchronous event callback

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Airslash
    New Member
    • Nov 2007
    • 221

    #1

    Asynchronous event callback

    Hello,

    I have designed a basic wrapper around the UDP socket from the .NET framework, that resembles an UDP server.

    Whenever I recieve data, I wish to raise an asynchronous event. According the MSDN I need to use BeginInvoke and use EndInvoke to catch the result and cleanup the delegate.

    I however don't care about the result and just wish to fire the event asynchronous and carry on. The code is below of the class:

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;
    
    namespace ServerTest
    {
        public delegate void UDPDataEvent(string remote_ip, int remote_port, byte[] data, int byte_count);
    
        class UDPServer
        {
            public event UDPDataEvent OnData;
    
            public UDPServer(int listenport)
            {
                m_udp = new UdpClient(listenport);
                Port = listenport;
            }
    
            public int Port
            {
                get { return m_port; }
                set { m_port = value; }
            }
    
            public void Start()
            {
                // Configure the thread and start it.
                m_keep_listening = true;
                m_listenthread = new Thread(new ThreadStart(Listen));
                m_listenthread.Start();
            }
    
            public void Stop()
            {
                // Configure the thread and stop it.
                m_keep_listening = false;
                m_listenthread.Abort();
            }
    
            /// <summary>
            /// Sends the array of bytes to the specified client and returns the amount of bytes that
            /// have been sent.
            /// </summary>
            /// <param name="data">The byte array of data to transmit.</param>
            /// <param name="ip">The remote address to send the data to.</param>
            /// <param name="port">The remote port to send the data to.</param>
            /// <returns></returns>
            public int Send(byte[] data, string ip, int port)
            {
                // Use our client object to send the data on the fly to the specified destination.
                return m_udp.Send(data, data.Length, ip, port);
            }
    
            private void Listen()
            {
                while (m_keep_listening)
                {
                    // Create a new IPEndPoint that will listen on the specified port
                    // for incoming data.
                    IPEndPoint RemoteEndPoint = new IPEndPoint(IPAddress.Any, Port);
    
                    // Now we'll recieve the UDP message from the socket. Note that this call
                    // is  a blocking call untill an actuall UDP message has been recieved from
                    // the client. Because we don't wish to hang indefinitly, we will poll the
                    // data avaialble from the socket to read.
                    if (m_udp.Available > 0)
                    {
                        // There is data available, so read out that data from the socket and
                        // raise the event.
                        byte[] data = m_udp.Receive(ref RemoteEndPoint);
    
                        // Raise the event of our server so we can process the data.
                        if (OnData != null)
                            OnData.BeginInvoke(RemoteEndPoint.Address.ToString(), RemoteEndPoint.Port, data, data.Length, CleanCallbackEvent, null);
                    }
                }
            }
    
            /// <summary>
            /// This function handles the cleaning of the delegate that was used to fire the event
            /// asynchronous from the processing thread.
            /// </summary>
            /// <param name="result"></param>
            private void CleanCallbackEvent(IAsyncResult result)
            {
                try
                {
                    UDPDataEvent eventcallback = (UDPDataEvent)result.AsyncState;
                    eventcallback.EndInvoke(result);
                }
            }
    
            private UdpClient m_udp;        // The UDP component from the .NET framework.
            private int m_port;             // The port we bind ourselves too to listen on for data.
            private Thread m_listenthread;  // Thread that listends for incoming data from the UDPSocket.
            private bool m_keep_listening;  // Flag that keeps the listenthread running.
            
        }
    }
    The problem is now the calbackroutine 'CleanCallbackE vent'. I always end up in the except block. What am I supposed to change to handle the callback properly without errors & leaks?
  • Christian Binder
    Recognized Expert New Member
    • Jan 2008
    • 218

    #2
    What does exactly happen, which Exception is thrown, what's the exception's message?

    Does your code even compile, because there's a catch-statement missing after line 94?

    Comment

    • Airslash
      New Member
      • Nov 2007
      • 221

      #3
      the catch is there, forgot to copy&paste it.

      Application crashes completly when the callback is occuring and the windows event log tells its a nullpointer error.

      Comment

      • Christian Binder
        Recognized Expert New Member
        • Jan 2008
        • 218

        #4
        On line 92 you cast result.AsyncSta te to UDPDataEvent. The value of AsyncState represents the last parameters value of line 78, so it's null.

        I've tried it and it worked if you're doing it that way:
        Code:
            
        private void CleanCallbackEvent(IAsyncResult result) {
              try {
                //UDPDataEvent eventcallback = (UDPDataEvent)result.AsyncState;
                //eventcallback.EndInvoke(result);
                AsyncResult asyncResult = result as AsyncResult;  
                (asyncResult.AsyncDelegate as UDPDataEvent).EndInvoke(result);
              } catch { 
              }
            }

        Comment

        • Airslash
          New Member
          • Nov 2007
          • 221

          #5
          cheers, i'll give it a go.

          Comment

          Working...