2009-08-30 17 views
6

Tengo una clase (NamedPipeManager) que tiene un hilo (PipeThread) que espera una conexión NamedPipe usando (ConnectNamedPipe) y luego lee (ReadFile) - estas son llamadas de bloqueo (no superpuestas) - sin embargo, aparece un señalar cuando quiero desbloquearlos, por ejemplo, cuando la clase de llamada intenta detener el NamedPipeManager ...¿Cómo desbloquear ConnectNamedPipe y ReadFile? [C#]

¿Cómo puedo interrumpirlo? ¿Usando Thread.abort? Thread.interrupt? ¿Hay una forma adecuada de manejar esto? Consulte el código de abajo que ilustra mi situación actual

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 
} 
}; 

Así, en función stop() - ¿cómo podría gracia desbloquear la llamada a ConnectNamedPipe (...) o ReadFile (...)?

Cualquier ayuda sería apreciada. Gracias,

Respuesta

4

Comenzando con Windows Vista, hay una operación CancelSynchronousIO disponible para los hilos. No creo que haya un contenedor de C#, por lo que necesitaría usar PInvoke para llamarlo.

Antes de Vista, no hay realmente una manera de realizar una operación de este tipo con elegancia. Aconsejaría no utilizar la cancelación de subprocesos (lo que podría funcionar, pero no califica como gracioso). Su mejor enfoque es usar IO superpuesto.

+0

¿Esto se aplica a ambos casos (ConnectNamedPipe y ReadFile)? Puedo encontrar una manera de pasar ConnectNamedPipe falsificando una conexión que la desbloqueará y luego saldrá (en base a un bool) - pero no puedo ver cómo puedo desbloquear un ReadFile cada vez ... ¿Cómo es esto usualmente? ¿hecho? Tiene que haber alguna forma no asincrónica de manejar esta situación. – Shaitan00

+0

BTW - esto es para ejecutar en Windows 2000 y XP ... no Vista en el corto plazo ... También usando .Net 2.0 ... Gracias, – Shaitan00

+0

Una forma sería especificar un tiempo de espera en todas las operaciones, y luego esencialmente realice un sondeo (es decir, realice una operación de lectura para, digamos, 1s, luego verifique si el hilo debe abortarse, si no, continúe leyendo). Sin embargo, parece que Microsoft realmente no cree en los tiempos de espera, por lo que no hay API para especificarlos. Consulte también http://stackoverflow.com/questions/593175/breaking-readfile-blocking-named-pipe-windows-api –

3

Parece estar trabajando en VC6.0, WinXP Si intento de interrumpir ConnectNamedPipe por DeleteFile("\\\\.\\pipe\\yourpipehere");

Así que indicar el nombre, no manejar.

+0

De hecho, DeleteFile internamente abre el manejador de archivo por nombre, por lo que esto es equivalente a llamar a CreateFile(). –

Cuestiones relacionadas