2009-08-30 6 views
6

Ho una classe (NamedPipeManager) che ha un thread (PipeThread) che aspetta una connessione NamedPipe usando (ConnectNamedPipe) e poi legge (ReadFile) - queste sono chiamate di blocco (non sovrapposte) - tuttavia arriva un punto quando voglio sbloccarli - per esempio quando la classe chiamante tenta di fermare NamedPipeManager ...Come sbloccare ConnectNamedPipe e ReadFile? [C#]

Come posso interromperlo? Utilizzando Thread.abort? Thread.interrupt? C'è un modo corretto per gestire questo? Fare riferimento al codice qui sotto, che illustra la mia situazione attuale

main() 
{ 
    NamedPipeManager np = new NamedPipeManager(); 
     ... do stuff ... 
    ... do stuff ... 
    np.Stop();  // at this point I want to stop waiting on a connection 
} 


class NamedPipeManager 
{ 
private Thread PipeThread; 

public NamedPipeManager 
{ 
    PipeThread = new Thread(new ThreadStart(ManagePipes)); 
    PipeThread.IsBackground = true; 
    PipeThread.Name = "NamedPipe Manager"; 
    PipeThread.Start(); 
} 

private void ManagePipes() 
{ 
    handle = CreateNamedPipe(..., PIPE_WAIT, ...); 
    ConnectNamedPipe(handle, null);  // this is the BLOCKING call waiting for client connection 

    ReadFile(....);    // this is the BLOCKING call to readfile after a connection has been established 
    } 


public void Stop() 
{ 
    /// This is where I need to do my magic 
    /// But somehow I need to stop PipeThread 
    PipeThread.abort();  //?? my gut tells me this is bad 
} 
}; 

Così, in funzione Stop() - come avrei sbloccare con grazia la chiamata a ConnectNamedPipe (...) o ReadFile (...)?

Qualsiasi aiuto sarebbe apprezzato. Grazie,

risposta

4

A partire da Windows Vista, è disponibile l'operazione CancelSynchronousIO per i thread. Non penso che ci sia un wrapper C# per questo, quindi dovresti usare PInvoke per chiamarlo.

Prima di Vista, non c'è davvero un modo per eseguire questa operazione con garbo. Vorrei sconsigliare l'uso dell'annullamento del thread (che potrebbe funzionare, ma non si qualifica come aggraziato). Il tuo approccio migliore è usare l'IO sovrapposto.

+0

Questo vale per entrambi i casi (ConnectNamedPipe & ReadFile)? Posso trovare un modo per superare ConnectNamedPipe facendo finta una connessione che si sbloccherà e poi uscirà (basato su un bool) - ma non riesco a vedere come posso sbloccare un ReadFile ... Come è questo di solito fatto? Ci deve essere un modo non asincrono di gestire questa situazione. – Shaitan00

+0

BTW - questo è per funzionare su Windows 2000 e XP ... no Vista in qualsiasi momento presto .. Anche usando .Net 2.0 ... Grazie, – Shaitan00

+0

Un modo sarebbe quello di specificare un timeout su tutte le operazioni, e quindi essenzialmente eseguire il polling (cioè eseguire un'operazione di lettura per, per esempio, 1s, quindi controllare se il thread deve interrompere, in caso contrario, continuare a leggere). Tuttavia, sembra che Microsoft non creda davvero nei timeout, quindi non ci sono API per specificarli. Vedi anche http://stackoverflow.com/questions/593175/breaking-readfile-blocking-named-pipe-windows-api –

3

Sembra di essere al lavoro su VC6.0, WinXP se provo a interrompere ConnectNamedPipe da DeleteFile("\\\\.\\pipe\\yourpipehere");

Quindi, basta specificare nome, non gestire.

+0

Infatti, DeleteFile apre internamente l'handle del file per nome, quindi equivale a chiamare CreateFile(). –