[英]C# problem with HttpListener
我使用HttpListener
編寫了一個Windows服務,以異步方式處理來自點的請求。
它工作正常,但有時它遇到一個問題,需要重新啟動服務或服務器來修復。 最初我用以下方法聲明了偵聽器對象:
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)
我認為當某個點將請求發送到服務器但在接收應答失去連接之前出現問題。
如何防止拋出異常? 響應對象會被自動妥善處理嗎? 我該如何解決這個問題?
我正在生產中使用HttpListener,我找到了解決這個問題的最好方法,而沒有添加一大堆try / catch塊,它們無法傳達手頭代碼的邏輯; 是非常簡單地設置Listener.IgnoreWriteExceptions = true;
而且,瞧不再寫異常了!
有一個相關的問題 。
你正在做的很好,因為關閉連接或連接被丟棄的另一方沒有其他任何事情可以做。 您可能希望捕獲確切的異常並調用output.Dispose()
和其他清理,或者只是讓終結器處理釋放,如果它不經常發生的話。
我最近遇到了同樣的問題,並通過將輸出包裝在try / catch中來解決它:
try
{
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
output.Write(buffer, 0, buffer.Length);
}
catch (HttpListenerException)
{
// Handle error caused by connection being lost
}
問題解決了!!! 我剛刪除了這個:
finally
{
PointsListener.BeginGetContext(PointProcessRequest, PointsListener);
}
並在PointProcessRequest方法的開頭插入此命令!
IAsyncResult _result = listener.BeginGetContext(new AsyncCallback(PointProcessRequest), listener);
問題解決了100%!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.