SocketAsyncEventArgs Class

Namespace: System.Net.Sockets
Assembly: System.Net.Sockets.dll

Represents the state of an asynchronous socket operation.

Remarks

The SocketAsyncEventArgs class is designed to be reusable. When an asynchronous socket operation completes, the SocketAsyncEventArgs object is returned to the application's pool of reusable event arguments. This improves performance by reducing the overhead of allocating and deallocating memory for new objects.

This class implements a pool-based design. Applications should obtain an instance of this class from a pool, use it for an operation, and then return it to the pool when finished.

The following methods on the Socket class use SocketAsyncEventArgs:

Properties

Methods

Events

Example

The following example demonstrates how to create a reusable SocketAsyncEventArgs object, use it for a receive operation, and then return it to a pool.


using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class SocketExample
{
    private Socket _socket;
    private SocketAsyncEventArgs _socketArgs;
    private byte[] _buffer = new byte[1024];

    public SocketExample(Socket socket)
    {
        _socket = socket;
        _socketArgs = new SocketAsyncEventArgs();
        _socketArgs.Completed += OnOperationCompleted;
        _socketArgs.SetBuffer(_buffer, 0, _buffer.Length);
    }

    public void StartReceive()
    {
        bool willRaiseEvent = _socket.ReceiveAsync(_socketArgs);
        if (!willRaiseEvent)
        {
            ProcessReceive(_socketArgs);
        }
    }

    private void OnOperationCompleted(object sender, SocketAsyncEventArgs e)
    {
        ProcessOperation(e);
    }

    private void ProcessOperation(SocketAsyncEventArgs e)
    {
        // Handle the operation completion based on e.LastOperation
        switch (e.LastOperation)
        {
            case SocketAsyncOperation.Receive:
                ProcessReceive(e);
                break;
            case SocketAsyncOperation.Send:
                ProcessSend(e);
                break;
            // Handle other operations as needed
            default:
                Console.WriteLine($"Unhandled operation: {e.LastOperation}");
                break;
        }

        // Return the EventArgs object to the pool if you are using one
        // e.Dispose(); // Or return to a pool
    }

    private void ProcessReceive(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success && e.BytesTransferred > 0)
        {
            // Process received data
            string receivedData = System.Text.Encoding.ASCII.GetString(e.Buffer, e.Offset, e.BytesTransferred);
            Console.WriteLine($"Received: {receivedData}");

            // Continue receiving
            StartReceive();
        }
        else
        {
            // Handle errors or disconnection
            Console.WriteLine($"Receive failed: {e.SocketError}");
            // e.Dispose(); // Or return to a pool
        }
    }

    private void ProcessSend(SocketAsyncEventArgs e)
    {
        if (e.SocketError == SocketError.Success)
        {
            Console.WriteLine($"Sent {e.BytesTransferred} bytes.");
            // Optionally start next send or close connection
        }
        else
        {
            Console.WriteLine($"Send failed: {e.SocketError}");
            // e.Dispose(); // Or return to a pool
        }
    }
}