2013-12-16 4 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, либо 111111111 или случайным образом смешанным, как A1A1111AAAA1?

Должен ли я избегать этого способа отправки полностью и блокировать отправку, пока не закончится другой поток?

+3

Вам нравится думать об этом? Нет? Затем избегайте ситуаций, когда необходимо задавать такие вопросы. –

+0

Я отредактировал ваш заголовок. Пожалуйста, смотрите: «Если вопросы включают« теги »в их названиях?] (Http://meta.stackexchange.com/questions/19190/), где консенсус« нет, они не должны ». –

+0

Lol Что не так с попыткой предсказать поведение кода? Это законный вопрос У меня есть многопоточное приложение, в котором каждый поток может иметь некоторые данные для отправки. Если их поведение без блокировок является последовательным и заканчивается либо AAAAAAAAA11111111111, либо 11111111AAAAAA, мне не нужно будет реализовывать блокировки. – InstallGentoo

ответ

2

Должен ли я избегать этого способа отправки целиком и блокировать отправку, пока не закончится другой поток?

Да и нет, вы должны избегать этого полностью, но нет необходимости блокировать отправку до окончания другой резьбы.

Что вы можете сделать, это иметь 3-й поток, который несет ответственность за отправку данных и ваших двух потоков, которые должны отправлять данные, помещая свои данные в очередь с потоком. Затем отправляющий поток будет деактивировать выполняемую работу и отправить ее на провод.

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); 
} 
Смежные вопросы