2009-09-01 10 views
5

Tengo un hilo de trabajo en mi aplicación que es responsable de tres cosas diferentes. Las solicitudes para dos de los trabajos aparecen en Colas que he escrito, el otro trabajo se activa cuando aparece una solicitud en una transmisión de red. Me gustaría que mi hilo de trabajo espere cuando no haya trabajo por hacer. Esto es fácil con las dos Colas, ya que exponen un evento ManualResetEvent que se establece cuando tienen elementos, sin embargo, el NetworkStream no parece tener esto. NetworkStream ha sido recuperado de un TcpClient.¿Cómo esperas que un flujo de red tenga datos para leer?

lo que busco es el código que se ve algo como esto:

while (notDone) 
{ 
    WaitHandle.WaitAny(new WaitHandle[] { queue1.HasData, queue2.HasData, netStream.HasData }); 
    // ... 
    if (netStream.DataAvailable) 
    { 
     netStream.Read(buffer, 0, 20); 
     // process buffer 
    } 
} 

¿Alguien sabe una manera de conseguir un WaitHandle que se establece cuando un NetworkStream tiene datos?

Respuesta

7

Puede usar los métodos asíncronos de NetworkStream y establecer un evento ManualResetEvent en el método EndReceive.

// ... 
netStream.BeginRead(buffer, offset, callback, state); 
// ... 

dentro del método de devolución de llamada

netStream.EndRead(ar); 
netStreamManualResetEvent.Set(); 

entonces su código

while (notDone) 
{ 
    WaitHandle.WaitAny(new WaitHandle[] { queue1.HasData, queue2.HasData, netStreamManualResetEvent}); 
    // ... 
    if (netStream.DataAvailable) 
    { 
     // make the buffer from the AsyncState in the callback method available here 
     // process buffer 
    } 
} 
+0

¿Es posible obtener el BeginRead para leer bytes cero? –

+0

Si el host remoto apaga la conexión y no hay más datos disponibles, se leerán 0 bytes. ¿Por qué preguntas? – SpaceghostAli

+0

Si no puede hacer que BeginRead lea cero bytes, comienza a tener que administrar el búfer de lectura entre el bucle principal y la devolución de llamada. Esto es totalmente factible pero no es tan bueno como me gustaría. –

2

La manera más simple es, probablemente, utilizar un hilo adicional que se lee de forma síncrona y pone datos adicionales en una cola adicional.

Alternativamente, podría utilizar IO asíncrono, pero eso es un poco complicado, y aún tendría que tener alguna cola adicional.

Aunque Socket tiene un método Select() (y se puede conseguir en una toma de corriente de un NetworkStream) No creo que expone esta función de una manera que le permite mezclar con otros tipos de mangos de espera.

Cuestiones relacionadas