You can’t timeout or cancel asynchronous Socket
operations.
All you can do is start your own Timer
which closes the Socket
—the callback will then be immediately called and the EndX
function will come back with an ObjectDisposedException
if you call it. Here's an example:
using System;
using System.Threading;
using System.Net.Sockets;
class AsyncClass
{
Socket sock;
Timer timer;
byte[] buffer;
int timeoutflag;
public AsyncClass()
{
sock = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
buffer = new byte[256];
}
public void StartReceive()
{
IAsyncResult res = sock.BeginReceive(buffer, 0, buffer.Length,
SocketFlags.None, OnReceive, null);
if(!res.IsCompleted)
{
timer = new Timer(OnTimer, null, 1000, Timeout.Infinite);
}
}
void OnReceive(IAsyncResult res)
{
if(Interlocked.CompareExchange(ref timeoutflag, 1, 0) != 0)
{
// the flag was set elsewhere, so return immediately.
return;
}
// we set the flag to 1, indicating it was completed.
if(timer != null)
{
// stop the timer from firing.
timer.Dispose();
}
// process the read.
int len = sock.EndReceive(res);
}
void OnTimer(object obj)
{
if(Interlocked.CompareExchange(ref timeoutflag, 2, 0) != 0)
{
// the flag was set elsewhere, so return immediately.
return;
}
// we set the flag to 2, indicating a timeout was hit.
timer.Dispose();
sock.Close(); // closing the Socket cancels the async operation.
}
}