Я написал службу Windows, используя HttpListener
для асинхронной обработки запросов из точек.Проблема с C# с HttpListener
Он отлично работает, но иногда он сталкивается с проблемой, требующей перезапуска службы или сервера для исправления. Первоначально я объявил объект слушателя:
public HttpListener PointsListener = new HttpListener();
Вот код метода, где я начинаю слушать. Я звоню его из OnStart
метода обслуживания:
public string ListenerStart()
{
try
{
if (!PointsListener.IsListening)
{
PointsListener.Prefixes.Add(String.Concat("http://*:", points_port, "/"));
PointsListener.Start();
PointsListener.BeginGetContext(PointProcessRequest, PointsListener);
LogWriter("Http listener activated on port " + points_port);
return "Listener started";
}
else
{
return "Listener is already started!";
}
}
catch (Exception err)
{
LogWriter("Error in LIstenerStart \r\n" + err.ToString());
return ("Error: " + err.Message);
}
}
Вот методы, обрабатывать запросы:
private void PointProcessRequest(IAsyncResult result)
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
HttpListenerResponse response = context.Response;
response.KeepAlive = false;
System.IO.Stream output = response.OutputStream;
try
{
//declaring a variable for responce
string responseString = "<html>My Response: request is not allowed by server protocol</html>";
// Commands and actions to set responceString
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
output.Write(buffer, 0, buffer.Length);
}
catch (Exception err)
{
LogWriter("Error in PointProcessRequest: \r\n" + err.ToString());
}
finally
{
try
{
output.Flush();
output.Close();
response.Close();
}
catch (Exception err)
{
LogWriter("Error in PointProcessRequest CLOSING OUTPUT STREAM: \r\n" + err.ToString());
}
finally
{
PointsListener.BeginGetContext(PointProcessRequest, PointsListener);
}
}
}
Это работает хорошо некоторое время, но появляется следующее сообщение об ошибке в бланк:
Error in PointProcessRequest:
System.Net.HttpListenerException: The specified network name is no longer available
в System.Net.HttpResponseStream.Write(Byte[] buffer, Int32 offset, Int32 size)
в ARK_Dealer.ark.PointProcessRequest(IAsyncResult result)
[26.01.2011 9:00:54] Error in PointProcessRequest CLOSING OUTPUT STREAM:
System.InvalidOperationException: Cannot close stream until all bytes are written.
в System.Net.HttpResponseStream.Dispose(Boolean disposing)
в System.IO.Stream.Close()
в ARK_Dealer.ark.PointProcessRequest(IAsyncResult result)
Я думаю, что проблема возникает, когда какая-то точка отправляет запрос на сервер, но до того, как принимающий ответ теряет соединение.
Как я могу предотвратить исключение исключения? Будет ли объект ответа правильно удаляться автоматически? Как я могу решить проблему?
Я немного закодировал метод PointProcess и вставил Dispose там, как вы писали. Позвольте мне контролировать систему несколько дней, чтобы увидеть, будет ли она вступать в силу или нет. Большое спасибо! – Khisrav
Привет! Прошу прокомментировать мое окончательное решение, при написании ответа на выходной поток я использую следующий код: using (System.IO.Stream output = response.OutputStream) { output.Write (buffer, 0, buffer.Length); } Если произойдет исключение, оно будет записано в журнал, и если код будет запущен, вывод объекта будет удален автоматически. Я прав? Спасибо! – Khisrav
Вы все еще закрываете объект 'response'? – Amir