2009-09-01 12 views
5

Ho un thread di lavoro nella mia applicazione che è responsabile di tre cose diverse. Le richieste per due dei lavori vengono visualizzate in code che ho scritto, l'altro lavoro viene attivato quando viene visualizzata una richiesta su un flusso di rete. Vorrei che il mio thread di lavoro attenda quando non c'è lavoro da fare. Questo è facile con le due code in quanto espongono un oggetto ManualResetEvent impostato quando dispongono di elementi, tuttavia il NetworkStream non sembra avere questo. NetworkStream è stato recuperato da un TcpClient.Come si aspetta che un flusso di rete abbia i dati da leggere?

Quello che cerco è il codice che sembra qualcosa di simile:

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

Qualcuno sa un modo per ottenere un WaitHandle che viene impostato quando un NetworkStream ha dati?

risposta

7

È possibile utilizzare i metodi asincroni di NetworkStream e impostare ManualResetEvent nel metodo EndReceive.

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

all'interno del metodo di callback

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

quindi il codice

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

E 'possibile ottenere il BeginRead a leggere zero byte? –

+0

Se l'host remoto interrompe la connessione e non ci sono più dati disponibili, verranno letti 0 byte. Perché lo chiedi? – SpaceghostAli

+0

Se non riesci a leggere BeginRead a zero byte, devi iniziare a gestire il buffer di lettura tra il loop principale e la richiamata. Questo è totalmente fattibile ma non è bello come vorrei. –

2

Il modo più semplice consiste probabilmente nell'utilizzare un thread aggiuntivo che legge in modo sincrono e inserisce dati aggiuntivi in ​​una coda aggiuntiva.

In alternativa, è possibile utilizzare l'IO asincrono, ma è un po 'complicato - e sarà comunque necessario disporre di una coda aggiuntiva.

Anche se Socket ha un metodo Select() (e si può arrivare a una presa di corrente da un NetworkStream) Non credo che espone questa funzionalità in un modo che consente di mescolare con altri tipi di maniglie di attesa.

Problemi correlati