.NET Framework Class Library for Silverlight
SocketAsyncEventArgs Class

Represents an asynchronous socket operation.

Namespace:  System.Net.Sockets
Assembly:  System.Net (in System.Net.dll)
Syntax

Visual Basic (Declaration)
Public Class SocketAsyncEventArgs _
    Inherits EventArgs _
    Implements IDisposable
Visual Basic (Usage)
Dim instance As SocketAsyncEventArgs
C#
public class SocketAsyncEventArgs : EventArgs, 
    IDisposable
Remarks

The SocketAsyncEventArgs class provides an asynchronous pattern used by socket applications. The main feature of this pattern is the avoidance of the repeated allocation and synchronization of objects during asynchronous socket I/O.

In the System.Net.Sockets..::.Socket class, asynchronous socket operations are described by reusable SocketAsyncEventArgs objects allocated and maintained by the application. Socket applications know best the amount of overlapped socket operations that must be sustained. The application can create as many of the SocketAsyncEventArgs objects that it needs. For example, if an application needs to have 15 socket send or receive operations outstanding at all times to support outgoing client connection rates, it can allocate 15 reusable SocketAsyncEventArgs objects for that purpose.

The pattern for performing an asynchronous socket operation with this class consists of the following steps:

  1. Allocate a new SocketAsyncEventArgs object, or get a free one from an application pool.

  2. Set properties on the SocketAsyncEventArgs object required for the operation about to be performed (the completion callback delegate method, the data buffer, the offset into the buffer, and the maximum amount of data to transfer for the ReceiveAsync and SendAsync methods, for example).

  3. Call the appropriate socket method (ConnectAsync, ReceiveAsync, or SendAsync) to initiate the asynchronous operation.

  4. If the asynchronous socket method returns true, the I/O operation is pending. The SocketAsyncEventArgs..::.Completed event on the System.Net.Sockets..::.SocketAsyncEventArgs object passed to the socket method will be raised upon completion of the operation. When the event is raised in the event handler, query the SocketAsyncEventArgs properties for the completion status and socket operation result (the amount of received data in the buffer for ReceiveAsync method call, for example).

  5. If the asynchronous socket method returns false, the operation completed synchronously. The SocketAsyncEventArgs properties may be queried for the completion status and socket operation result.

  6. Reuse the SocketAsyncEventArgs object for another operation, put it back in the pool, or discard it.

The lifetime of the new SocketAsyncEventArgs object used in an asynchronous socket operation is determined by references in the application code and asynchronous I/O references. It is not necessary for the application to retain a reference to a SocketAsyncEventArgs object after it is submitted as a parameter to one of the asynchronous socket methods. It will remain referenced until the completion callback returns. However it is advantageous for the application to retain the reference to the SocketAsyncEventArgs object so that it can be reused for a future asynchronous socket operation.

Examples

The following example creates two instances of the SocketAsyncEventArgs class, one for use with the ConnectAsync method and one for use with the ReceiveAsync method. The SocketAsyncEventArgs instance for use on the connect operation still needs the RemoteEndPoint property set to a DnsEndPoint instance for the host before the ConnectAsync method is called.

C#
  public class Example
  {
    static ManualResetEvent clientDone = new ManualResetEvent(false);

    public static void Demo(System.Windows.Controls.TextBlock outputBlock)
    {

        SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
            DnsEndPoint hostEntry = new DnsEndPoint("http://www.contoso.com", 80);

        // Create a socket and connect to the server
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        socketEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(SocketEventArg_Completed);

        socketEventArg.RemoteEndPoint = hostEntry;
        socketEventArg.UserToken = sock;
        sock.ConnectAsync(socketEventArg);
        clientDone.WaitOne();
    }

    // A single callback is used for all socket operations. 
    // This method forwards execution on to the correct handler 
    // based on the type of completed operation
    static void SocketEventArg_Completed(object sender, SocketAsyncEventArgs e)
    {
        switch (e.LastOperation)
        {
            case SocketAsyncOperation.Connect:
                ProcessConnect(e);
                break;
            case SocketAsyncOperation.Receive:
                ProcessReceive(e);
                break;
            case SocketAsyncOperation.Send:
                ProcessSend(e);
                break;
            default:
                throw new Exception("Invalid operation completed");
        }
    }

    // Called when a ConnectAsync operation completes
    private static void ProcessConnect(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // Successfully connected to the server

            // Send 'Hello World' to the server
            byte[] buffer = Encoding.UTF8.GetBytes("Hello World");
            e.SetBuffer(buffer, 0, buffer.Length);
            Socket sock = e.UserToken as Socket;
            bool willRaiseEvent = sock.SendAsync(e);
            if (!willRaiseEvent)
            {
                ProcessSend(e);
            }
        }
        else
        {
            throw new SocketException((int)e.SocketError);
        }
    }

        // Called when a ReceiveAsync operation completes
        // </summary>
    private static void ProcessReceive(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // Received data from server

        // Data has now been sent and received from the server. 
        // Disconnect from the server
            Socket sock = e.UserToken as Socket;
            sock.Shutdown(SocketShutdown.Send);
            sock.Close();
            clientDone.Set();
        }
        else
        {
            throw new SocketException((int)e.SocketError);
        }
    }


    // Called when a SendAsync operation completes
    private static void ProcessSend(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            // Sent "Hello World" to the server successfully

            //Read data sent from the server
            Socket sock = e.UserToken as Socket;
            bool willRaiseEvent = sock.ReceiveAsync(e);
            if (!willRaiseEvent)
            {
                ProcessReceive(e);
            }
        }
        else
        {
            throw new SocketException((int)e.SocketError);
        }
    }
  }
Inheritance Hierarchy

System..::.Object
  System..::.EventArgs
    System.Net.Sockets..::.SocketAsyncEventArgs
Thread Safety

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.
Platforms

For a list of the operating systems and browsers that are supported by Silverlight, see Supported Operating Systems and Browsers.

See Also

Reference

Tags :


Page view tracker