Pregunta

Estoy usando un NetworkStream y TcpClient para recibir de forma asíncrona de datos utilizando BeginRead. Necesito solicitar un tiempo muerto a esta operación, de tal manera que después de un período de tiempo especificado se abortará la lectura.

Por lo que yo soy capaz de decir, esto no se admite en NetworkStream o TcpClient - hay una propiedad ReceiveTimeout, pero esto parece sólo se aplican a la síncrona equivalente - 'leer'

.

A pesar de la clase Socket subyacente no parece que los tiempos de espera de apoyo en su método BeginReceive.

he buscado en este tema y la resolución única sugerido que he visto es configurar otro subproceso de fondo para cancelar la operación si no se completa dentro del período de tiempo de espera. Este parece ser un horrible truco. Sin duda, hay una manera mejor?

¿Fue útil?

Solución

Es la única manera de hacerlo, porque cuando se está utilizando una operación asíncrona, el hilo que inició la operación está fuera haciendo otra cosa. El tiempo de espera está disponible con la versión sincrónica porque el hilo de ejecución se bloquea hasta que se complete la operación de lectura.

Si usted tendría que usar un subproceso de fondo para cancelar la operación, sin embargo, no habría mucho sentido para continuar utilizando el asíncrona Begin / End métodos. Si vas para escindir un subproceso de fondo, simplemente realizar una operación síncrona Se lee en el subproceso de fondo, y luego se puede utilizar el ReceiveTimeout.

Otros consejos

ManualResetEvent con un valor de tiempo de espera para señal cuando haya terminado su tarea. Si el tiempo de espera antes de que se señaliza, entonces usted sabe que la operación asíncrona nunca 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 de devolución de llamada, el uso

private void ReceiveCallBack(IAsyncResult ar)
{
    /** Use ar to check if receive is correct and complete */
    receiveDone.Set();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top