2009-09-01 58 views
5

我在我的應用程序中有一個工作線程負責三個不同的事情。兩個作業的請求在我編寫的隊列中打開,另一個作業在網絡流上發出請求時激活。如果沒有工作要做,我希望我的工作線程能夠等待。使用這兩個隊列很容易,因爲它們暴露了在有項目時設置的ManualResetEvent,但是NetworkStream似乎沒有這個。 NetworkStream已從TcpClient中檢索。如何等待網絡數據流讀取數據?

我所後的代碼看起來是這樣的:

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

有誰知道一種方式來獲得時的NetworkStream具有數據時設置的WaitHandle的?

回答

7

您可以使用NetworkStream的異步方法並在EndReceive方法中設置ManualResetEvent。

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

回調方法

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

裏面那麼你的代碼

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

是否有可能得到的BeginRead閱讀零個字節? – 2009-09-02 11:32:36

+0

如果遠程主機關閉連接並且沒有更多數據可用,則將讀取0個字節。你爲什麼要問? – SpaceghostAli 2009-09-02 13:05:31

+0

如果您無法使BeginRead讀取零字節,則必須開始管理主循環和回調之間的讀取緩衝區。這是完全可行的,但並不像我想的那麼好。 – 2009-09-03 15:22:04

2

最簡單的方法可能是使用一個額外的線程同步讀取並將額外的數據放到一個額外的隊列中。

或者你可以使用異步IO,但這有點棘手 - 你仍然需要一些額外的隊列。

雖然SocketSelect()方法(你可以從NetworkStream插座獲得)我不相信它公開的方式,它可以讓你與其他類型的等待句柄的混了此功能。