此問題與設計或模式以及要使用的不相關。這個問題的核心是關於線程和阻塞的情況。長時間阻塞方法。阻塞,睡眠,開始/結束和異步之間的區別
本示例適用於任何旨在連續執行相同操作的阻止方法。在這種情況下,它是在網絡流上阻塞讀取或寫入。在這些方法之間的線程和性能背後有什麼明顯的區別嗎?
我的假設是,下面的每個方法創建一個線程或使用池線程。然後阻塞該線程直到有數據被讀取。話雖如此,在這種情況下,這些方法之間的線程化,性能和可伸縮性是否有明顯的區別?
目前我正在創建一個服務器應用程序。此應用程序將有1000個客戶端創建TCP連接。這些連接將保持打開狀態,經常發送和接收少量數據。我期待使用模型A,因爲它是最容易實現的,也是最易維護的。無論選擇哪種模式,我最終是否會有1000個線程?
請注意,這些方法只是爲了給出一個結構的概念,而不是沒有適當的流讀取,超時和異常處理時會使用的。
方法A:阻止
Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
while(true)
{
TcpClient.Read();
}
}
方法B:休眠
Task.Factory.StartNew(ReadMessage,TaskCreationOptions.LongRunning);
private void ReadMessage()
{
while(true)
{
if(TcpClient.DataAvailable)
TcpClient.Read();
else
Thread.Sleep(1);
}
}
方法C:遞歸開始/結束
private void ReadMessage()
{
stream.BeginRead(readCallBack)
}
private void readCallBack()
{
stream.EndRead();
stream.BeginRead(readCallBack)
}
方法d:異步從BCL socket.ReceiveAsync( )
private void readCallBack()
{
while(true)
{
await socket.ReceiveAsync(eventArgs);
}
}
方法E:異步方法與阻塞讀(使用方法d打電話,但一個自定義的方法,而不是使用內置的從BCL插座exstendion)
private async Task<byte[]> ReceiveAsync()
{
return await Task.Factory.StartNew(() => TcpClient.Read());
}
謝謝你的解釋。它確實有幫助。我的最後一個問題是,方法D和新方法E有什麼不同?方法E會不會阻塞線程和使用IOCP呢? – 2013-02-25 22:01:27
「異步」方法中的阻塞I/O調用從來就不是一個好主意。方法E會阻塞調用線程而不使用IOCP。方法C和D使用IOCP並且不阻塞調用線程。 – 2013-02-26 00:34:41
根據您的建議修正方法E.我想,答案仍然是,它會阻止一個線程,而不是使用IOCP – 2013-02-26 04:26:08