2009-08-30 6 views
6

Ich habe eine Klasse (NamedPipeManager), die einen Thread (PipeThread) hat, der auf eine NamedPipe-Verbindung mit (ConnectNamedPipe) wartet und dann liest (ReadFile) - das sind blockierende Aufrufe (nicht überlappend) - aber es kommt a Punkt, wenn ich sie entsperren möchte - zum Beispiel wenn die aufrufende Klasse versucht, den NamedPipeManager zu stoppen ...Wie entsperren ConnectNamedPipe und ReadFile? [C#]

Wie kann ich es unterbrechen? Verwenden von Thread.abort? Thread.Unterbrechung? Gibt es einen richtigen Weg, damit umzugehen? auf den Code finden, unter dem veranschaulicht meine aktuelle Situation

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

in Funktion Stopp Also,() - wie würde ich den Anruf zu ConnectNamedPipe graziös entsperren (...) oder Readfile (...)?

Jede Hilfe wäre willkommen. Danke,

Antwort

4

Ab Windows Vista ist eine CancelSynchronousIO Operation für Threads verfügbar. Ich denke nicht, dass es einen C# -Wrapper dafür gibt, also müssten Sie PInvoke verwenden, um es aufzurufen.

Vor Vista gibt es nicht wirklich eine Möglichkeit, eine solche Operation anmutig durchzuführen. Ich würde davon abraten, Thread-Löschung (die funktionieren könnte, aber nicht als anmutig) zu verwenden. Ihre beste Vorgehensweise besteht darin, überlappende IO zu verwenden.

+0

Gilt dies für beide Fälle (ConnectNamedPipe & ReadFile)? Ich kann einen Weg finden, über ConnectNamedPipe vorbei zu täuschen, indem ich eine Verbindung vortäusche, die es entsperrt und dann beendet (basierend auf einem Bool) - aber ich kann nicht sehen, wie ich ein ReadFile jemals entsperren kann ... Wie ist das normalerweise erledigt? Es muss eine nicht asynchrone Möglichkeit geben, diese Situation zu bewältigen. – Shaitan00

+0

BTW - das ist unter Windows 2000 und XP laufen ... keine Vista jederzeit bald .. Auch mit. Net 2.0 ... Vielen Dank, – Shaitan00

+0

Eine Möglichkeit wäre, eine Zeitüberschreitung für alle Operationen, und dann im Wesentlichen Führen Sie eine Abfrage durch (dh führen Sie eine Leseoperation für zB 1s aus, dann prüfen Sie, ob der Thread abbrechen soll, wenn nicht, lesen Sie weiter). Es scheint jedoch, dass Microsoft wirklich nicht an Timeouts glaubt, also gibt es keine API, um sie zu spezifizieren. Siehe auch http://stackoverflow.com/questions/593175/breaking-readfile-blocking-named-pipe-windows-api –

3

Es scheint auf VC6.0 zu arbeiten, WinXP, wenn ich versuche ConnectNamedPipe von DeleteFile("\\\\.\\pipe\\yourpipehere");

Also nur Namen angeben zu unterbrechen, nicht handhaben.

+0

In der Tat, DeleteFile öffnet Dateihandle intern nach Name, das entspricht dem Aufruf von CreateFile(). –