2016-05-11 4 views
1

Я строю сервер Socket Socket. Мой код работает, но я не уверен, что это правильный способ сделать это.Правильный способ управления потоками

При подключении TcpClient Я помещаю его в новый объект со следующими Методами, затем вызываю Init(), чтобы начать проверять, доступны ли данные, когда доступны данные. Я вызываю событие, которое я слушаю, чтобы начать чтение буфера методы, использующие Я создал, как ReadInt32(), ReadByte(), ReadString() ReadObject<T>()

public void Init() 
    { 
     ThreadPool.QueueUserWorkItem(Read); 
    } 

    private void Read(object state) 
    { 
     if (IsClientConnected()) 
     { 
      if (_connected.Available > 0) 
      { 
       OnDataAvailable(_connected.Available); 
      } 
      Init(); 
     } 
    } 

должен ли я использовать While цикл здесь, или я должен перезапустить Init() как я сейчас делаю? Затем следует использовать BackgroundWorker, Thread или Task вместо ThreadPool?

Я также думал об изменении Init() к BeginWait(some sort of callback here) и удаление Init() внутри Read(), а затем просто позвонить BeginWait снова, где это необходимо

Моя цель, чтобы слушать команды и отвечать на команды. При одновременном соединении x число клиентов.

Так сценарий выглядит следующим образом:

У меня есть приложение, которое подключается к серверу. Затем сервер инициализирует новый объект с помощью TcpClient в качестве параметра в конструкторе. Затем сервер добавляет подключенного клиента в комнату с другим клиентом. В этом номере прослушивает каждый из событий клиента DataAvailable взгляд на следующие

private void Client_DataAvailable(ClientWrapper sender, int data) 
    { 
     var command = (Commands)Client.ReadByte(); 
     switch (command) 
     { 
      case Commands.RequestConnectId: // 1 

       var buffer = new WriteBuffer(Commands.RequestConnectId); 
       buffer.WriteInt32(sender.ConnectId); 
       sender.Reply(buffer); 

       break; 
      case Commands.WriteText: //2 

       var buffer = new WriteBuffer(Commands.WriteText); 
       buffer.WriteString(sender.ReadString()); 
       BroadCast(sender.ConnectId,buffer);//Send to the other client 

       break; 
     } 
    } 
+0

Правильный способ справиться с потоками в C# 5, чтобы не поточно ВООБЩЕ ввода/вывода. Вместо этого вы используете 'async' и' await' для вашей асинхронности. – Aron

+0

Любые предложения, как я могу заставить это применить 'async'' await' Я редактирую свой вопрос с дополнительной информацией о том, что я делаю –

+0

Ваш вопрос превысил объем приемлемого вопроса в StackOverflow. К сожалению, я не могу сообщить вам, какая сеть SE лучше подходит для этого вопроса. – Aron

ответ

1

Правильный способ чтения сокета, чтобы просто читать из него. Вызов не будет завершен, пока данные не будут готовы. Нет необходимости в мероприятиях. Свойство Available почти всегда является ошибкой, поэтому не используйте это.

Просто запустите:

var command = (Commands)Client.ReadByte(); 

немедленно. Хорошо запускать это на фоновом потоке (в отличие от того, что было предложено в комментариях). Потоки становятся проблемой, когда у вас их слишком много. Если вы поддерживаете несколько десятков подключений сокетов, это не проблема.

Вы также можете использовать асинхронный IO предпочтительно с await. Такая же идея применяется: просто прочитайте.

Если вы хотите обработать поток команды просто обернуть это в цикле:

while (true) { 
ReadCommand(); 
WriteResponse(); 
} 
Смежные вопросы