2013-12-16 82 views
-1

我有2個線程同時運行,並且每個被寫入socket.Send()流,螺紋Socket.Send()

While (soc.Connected) 
     { 


       byte[] byData = new byte[2]; 
       byData = System.Text.Encoding.ASCII.GetBytes("A"); 
       soc.Send(BitConverter.GetBytes(byData.Length)); 
       soc.Send(byData); 


     } 

其它線程使用完全相同的代碼,除了它發送「1」代替」。

另一端的數據將如何顯示?它會是AAAAAAAA還是111111111s的流或者像A1A1111AAAA1那樣隨機混合?

我應該避免這種完全發送的方式,並阻止發送,直到其他線程完成?

+3

你喜歡這樣想嗎?沒有?然後避免需要提問這樣的問題。 –

+0

我編輯過你的標題。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 –

+0

大聲笑試圖預測代碼行爲有什麼不對?這是一個合法的問題 我有一個多線程應用程序,其中每個線程可能有一些數據要發送。如果他們的行爲沒有鎖是一致的,並且以AAAAAAAAA11111111111或11111111AAAAAA結束,我就不必實現鎖。 – InstallGentoo

回答

2

我應該避免這種完全發送的方式,並阻止發送,直到其他線程完成?

是的,你應該完全避免這一點,但沒有必要阻止發送,直到其他線程完成。

你可以做的是有一個第三線程誰負責發送數據和你需要發送數據的兩個線程把他們的數據放到線程安全隊列。然後發送線程會將要完成的工作出列並通過線路發送出去。

const int MAX_QUEUE_LENGTH = 10; 
private BlockingCollection<MyMessageContainer> messageQueue = new BlockingCollection<MyMessageContainer>(new ConcurrentQueue<MyMessageContainer>(), MAX_QUEUE_LENGTH); 

void ProcessMessages() 
{ 
    foreach (var message in messageQueue.GetConsumingEnumerable()) 
    { 
     if(soc.Connected == false) 
      break; 

     soc.Send(message.ToPaylod()); 
    } 
} 

void GenerateMessageOne() 
{ 
    while(true) 
    { 
     messageQueue.Add(new MyMessageContainer("A")); 
    } 
} 

void GenerateMessageTwo() 
{ 
    while(true) 
    { 
     messageQueue.Add(new MyMessageContainer("1")); 
    } 
} 


class MyMessageContainer 
{ 
    public MyMessageContainer(string message) 
    { 
      _message = message; 
    } 

    private string _message; 

    public byte[] ToPayload() 
    { 
     var lengthBytes = BitConverter.GetBytes(byData.Length); 
     return lengthBytes.Concat(() => System.Text.Encoding.ASCII.GetBytes(_message)).ToArray(); 
    } 
} 

上面的代碼將讓在同一時間兩個線程隊列工作不阻塞,直到隊列達到MAX_QUEUE_LENGTH長,一旦有呼叫messageQueue.Add(現在就開始堵,直到發送線程有機會清理一些房間,一旦房間已經建成,它將解除其中一項功能並讓它繼續。

+0

這正是我要做的+1。 –

1

如果你想要隨機排序的輸出,最簡單的解決方案是簡單地鎖定實際寫入套接字的線。我也建議添加一個調用Thread.Sleep公平,雖然這是有些可選的。

While (soc.Connected) 
{ 
    byte[] byData = new byte[2]; 
    byData = System.Text.Encoding.ASCII.GetBytes("A"); 
    lock(soc) 
    { 
     soc.Send(BitConverter.GetBytes(byData.Length)); 
     soc.Send(byData); 
    } 
    Thread.Sleep(0); 
}