asynchronous - BeginReceive/BeginRead timeouts
tcpclient networkstream (2)
Es la única forma de hacerlo, porque cuando estás usando una operación asíncrona, el hilo que inició la operación está desactivado haciendo otra cosa. El tiempo de espera está disponible con la versión síncrona porque el hilo de ejecución está bloqueado hasta que se complete la operación de lectura.
Sin embargo, si tuviera que usar un hilo de fondo para cancelar la operación, no tendría sentido seguir utilizando los métodos asincrónicos de inicio / finalización. Si va a derivar un hilo de fondo, solo realice una operación de lectura sincrónica desde el hilo de fondo, y luego puede usar el ReceiveTimeout.
Estoy usando un NetworkStream & TcpClient para recibir datos de manera asincrónica usando BeginRead. Necesito aplicar un tiempo de espera a esta operación, de modo que después de un período de tiempo especificado la lectura se anule.
Hasta donde puedo decir, esto no es compatible con NetworkStream o TcpClient: hay una propiedad ReceiveTimeout, pero parece que esto solo se aplica al equivalente síncrono: ''Leer''.
Incluso la clase Socket subyacente no parece admitir los tiempos de espera en su método BeginReceive.
He buscado en este tema y la única resolución sugerida que he visto es configurar otra cadena de fondo para cancelar la operación si no se completa dentro del período de tiempo de espera. Esto parece un hack horrible. Seguramente hay una mejor manera?
Espere en ManualResetEvent con algún valor de tiempo de espera para indicar cuándo finaliza su tarea. Si se agota antes de que se señalice, entonces sabrá que la operación asincrónica nunca se completó.
private ManualResetEvent receiveDone = new ManualResetEvent(false);
receiveDone.Reset();
socket.BeginReceive(...);
if(!receiveDone.WaitOne(new TimeSpan(0, 0, 0, 30))) //wait for 30 sec.
throw new SocketException((int)SocketError.TimedOut);
Dentro de BeginReceive callback, use
private void ReceiveCallBack(IAsyncResult ar)
{
/** Use ar to check if receive is correct and complete */
receiveDone.Set();
}