2013-12-16 36 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); 
}