2009-08-30 125 views
6

我有一個類(NamedPipeManager),它有一個線程(PipeThread),它使用(ConnectNamedPipe)等待NamedPipe連接,然後讀取(ReadFile) - 這些阻止調用(不重疊) - 然而,點,當我想解除阻止他們 - 例如當呼叫類試圖停止NamedPipeManager ...如何取消阻止ConnectNamedPipe和ReadFile? [C#]

我該如何介入它?使用Thread.abort?了Thread.interrupt?有沒有適當的方法來處理這個問題? 請參閱下面的代碼這說明我目前的狀況

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

因此,在功能停止() - 我怎麼會優雅地疏通調用ConnectNamedPipe(...)或ReadFile的(...)?

任何幫助,將不勝感激。 謝謝,

回答

4

從Windows Vista開始,有一個可用於線程的CancelSynchronousIO操作。我不認爲它有一個C#包裝器,所以你需要使用PInvoke來調用它。

在Vista之前,沒有一種方法可以優雅地執行這樣的操作。我建議不要使用線程取消(這可能有效,但不符合優雅)。你最好的方法是使用重疊的IO。

+0

這是否適用於這兩種情況(ConnectNamedPipe&ReadFile)? 我可以找到一種方法,通過僞造一個連接來取消阻止它,然後退出(基於布爾),但我看不到如何解除阻止ReadFile ... 這是通常情況下如何通過ConnectNamedPipe做了什麼?處理這種情況必須有一些非同步的方式。 – Shaitan00

+0

順便說一句 - 這是運行在Windows 2000和XP ...沒有Vista的任何時間很快..也使用.Net 2.0 ... 謝謝, – Shaitan00

+0

一種方法是指定一個超時的所有操作,然後本質上執行輪詢(例如,對1s執行讀操作,然後檢查線程是否應該中止,如果不是,則繼續讀取)。但是,似乎微軟真的不相信超時,所以沒有API來指定它們。另請參閱http://stackoverflow.com/questions/593175/breaking-readfile-blocking-named-pipe-windows-api –

3

這似乎是工作在VC6.0,WinXP的,如果我試圖通過 DeleteFile("\\\\.\\pipe\\yourpipehere");

中斷ConnectNamedPipe所以只需指定名稱,無法處理。

+0

事實上,DeleteFile在內部按名稱打開文件句柄,所以這相當於調用CreateFile()。 –