2013-11-09 63 views
1
byte [] buffer = new byte [4]; 
buffer = "AAA"; 
this.networkStream.Write(buffer , 0 , 4); 
this.networkStream.Flush(); 

我可以啓動多個線程都使用同一個套接字同時通過一個套接字發送一個流?線程網絡流寫入相同的套接字

如果我有兩個線程,一個被髮送的4個字符AAA的緩衝區和其他線程BBB

將在另一端的數據看起來像AAABBB或混合字母ABABAB?

+1

您可能喜歡任何混合,但最可能的結果是AAABBB或BBBAAA。當tx堆棧緩衝區滿並且其中一個或另一個或兩個都被阻塞並且不能一次轉換所有的字符串時,更復雜的混合就成爲可能。爲了避免這種情況,您可以將字符串排隊到一個執行所有發送的線程。 –

+0

我會研究如何排隊我的BackgroundWorkers訪問相同的方法。非常感謝。 – InstallGentoo

回答

5

的文檔NetworkStream狀態:

讀寫操作可以同時上的NetworkStream類的一個實例 無需 同步進行。只要有一個用於寫入操作的唯一線程和一個用於讀取操作的獨特線程, 就不會在讀取和寫入線程之間產生交叉干擾,也不需要同步 。

因此,不應該有多個線程同時寫入流。你真的覺得需要有多個作者,那麼你需要通過lock(或其他一些機制)來同步對數據流的訪問。但是,如果你這樣做,那麼你將有效地以串行方式寫入流,所以爲什麼不簡化事情,只是構建你的代碼,以便實際上只有一個作者。

通過利用BlockingCollection類,使用一個作者的模式非常容易。這裏有一個簡單的例子來演示如何做到這一點。

public class Example 
{ 
    private NetworkStream networkstream = GetNetworkStream(); 
    private BlockingCollection<byte[]> queue = new BlockingCollection<byte[]>(); 

    public Example() 
    { 
    Task.Factory.StartNew(
    () => 
     { 
     foreach (byte[] buffer in queue.GetConsumingEnumerable()) 
     { 
      this.networkstream.Write(buffer, 0, buffer.Length); 
     } 
     }, TaskCreationOptions.LongRunning); 
    } 

    public void QueueWrite(byte[] buffer) 
    { 
    queue.Add(buffer); 
    } 
}