2011-12-29 1 views
2

У меня есть TcpListener, что при выключении все клиенты, находящиеся в процессе выполнения, бросают нижеследующее исключение, когда они пытаются позвонить по телефону EndAcceptTcpClient. Есть ли более грациозный шаблон, который я могу использовать для завершения всех существующих клиентских подключений до того, как TcpListener полностью отключится?Нужна более грациозная модель для закрытия TcpListener

System.ObjectDisposedException: не удается получить доступ к расположенному объекту. Имя объекта: 'System.Net.Sockets.Socket'. на System.Net.Sockets.Socket.EndAccept (IAsyncResult AsyncResult) в System.Net.Sockets.TcpListener.EndAcceptTcpClient (IAsyncResult AsyncResult)

Здесь приведен пример установки слушателя:

private TcpListener _requestListener; 

requestListener = new TcpListener(endPoint); 

requestListener.Start(1000); 

requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, null); 

Когда я пытаюсь закрыть слушатель я называю следующее. Это и приводит к вышеупомянутому исключению.

if (_requestListener != null) 
{ 
    _requestListener.Stop(); 
} 

Вот пример кода, который обрабатывает обратные вызовы, которые в конечном счете, осуществляются путем вызова слушателя Stop() метода

private void ServiceRequestInstanceHandler(IAsyncResult result) 
{ 
    try 
    { 
     using (TcpClient client = _requestListener.EndAcceptTcpClient(result)) 
     { 
      ProcessRequest(client); 
      client.Close(); 
     } 

     //Prepare to accept the next message 
     _requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, null); 
    } 
    catch (Exception ex) 
    { 
     if (_logger.IsErrorEnabled) 
      _logger.Error("An error occured while processing a service request. ", ex); 
    } 
} 

ответ

-1

Я считаю, чтобы избежать ошибок, вам необходимо пройти в вашем requestListener объекте к BeginAcceptTcpClient так:

requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, requestListener); 

Справочно: http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.beginaccepttcpclient.aspx

Я также хотел бы, лично, вновь написать свой метод, чтобы разрешить серверу принять новый клиент перед обработкой другого клиента, как так:

private void ServiceRequestInstanceHandler(IAsyncResult result) 
{ 
try 
    { 
     // You should probably check for a null result here, just in case 
     if(result == null) 
     { 
      throw new Exception("Result is null, cannot continue"); 
     } 
     using (TcpClient client = _requestListener.EndAcceptTcpClient(result)) 
     { 
      // Remember this line returns immediately/does not block 
      _requestListener.BeginAcceptTcpClient(ServiceRequestInstanceHandler, _requestListener); 
      ProcessRequest(client); 
      client.Close(); 
     } 
    } 
    catch (Exception ex) 
    { 
     if (_logger.IsErrorEnabled) 
      _logger.Error("An error occured while processing a service request. ", ex); 
    } 
} 

IIRC, Асинхронный материал работает в отдельном потоке.

Примечание: я не проверял выше код, но он должен решить вашу проблему :)

HTH

+0

пару вопросов ... (** 1 **) Так как '_requestListener' является никогда 'null', это все равно приведет к той же ошибке, не так ли? (** 2 **) Даже если я установлю его на «null» после его остановки, не помешало бы мне завершить запрос, который мы уже получили, и удалить любую возможность, чтобы я передал обратно запрашивающему, что полученное * запрос не будет обработан? – JoeGeeky

+0

@StuartBlacker Извините, я неправильно прочитал это. Я понимаю, что вы имеете в виду, и я сделаю это изменение, хотя я все еще не понимаю, как обращаться с запросами в полете. – JoeGeeky

+1

@JoeGeeky, 'BeginAcceptTcpClient' в вашем коде имеет два параметра, обратный вызов и состояние. В документации это показывает, что вам нужно передать 'TcpListener', чтобы он знал, какой TcpListener должен завершить accept. Поэтому, если вы передаете значение null для состояния и попробуйте вернуть его обратно, вы получаете доступ к объекту null (в данном случае удаленному). Опять же, я не тестировал, так что моя память может быть неправильной, но я подозреваю, что это так. Имеет ли это смысл? –

 Смежные вопросы

  • Нет связанных вопросов^_^