SocketAsyncEventArgs Class
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:
AcceptAsyncConnectAsyncDisconnectAsyncReceiveAsyncReceiveFromAsyncReceiveMessageFromAsyncSendAsyncSendPacketsAsyncSendToAsync
Properties
-
Boolean AcceptSocket
Gets or sets the accepted
Socketfor an accept operation. -
Int32 BytesTransferred
Gets the number of bytes transferred by the socket operation.
-
Object UserToken
Gets or sets a user-defined object that qualifies or contains context information about this asynchronous operation.
-
SocketError SocketError
Gets or sets the status code returned by the asynchronous socket operation.
-
Memory<Byte> Buffer
Gets the buffer that contains the data for the socket operation.
-
Int32 Offset
Gets the offset in the buffer where the data transfer begins.
-
Int32 Count
Gets the number of bytes in the buffer for the socket operation.
-
EndPoint RemoteEndPoint
Gets or sets the remote endpoint for the socket operation.
-
SocketFlags SocketFlags
Gets or sets the socket flags for the operation.
-
Boolean ReuseSocket
Gets or sets a value that indicates whether the socket can be reused after the operation completes.
-
IPPacketInfo ReceiveMessagePacketInfo
Gets information about the received packet, such as the interface and address.
-
Int32 RemotePort
Gets the remote port number for the socket operation.
Methods
-
Void Complete (Boolean forceDispose)
Completes the specified asynchronous socket operation.
Parameters:
- forceDispose:
Boolean-trueto force dispose of the object; otherwise,false.
- forceDispose:
-
Void SetBuffer (Byte[] buffer, Int32 offset, Int32 count)
Sets the buffer to be used for the socket operation.
Parameters:
- buffer:
Byte[]- The buffer to use. - offset:
Int32- The offset in the buffer where the data begins. - count:
Int32- The number of bytes in the buffer for the operation.
- buffer:
-
Void SetBuffer (Memory<Byte> buffer, Int32 offset, Int32 count)
Sets the buffer to be used for the socket operation.
Parameters:
- buffer:
Memory<Byte>- The buffer to use. - offset:
Int32- The offset in the buffer where the data begins. - count:
Int32- The number of bytes in the buffer for the operation.
- buffer:
Events
-
EventHandler<SocketAsyncEventArgs> Completed
Occurs when an asynchronous socket operation completes.
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
}
}
}