是否可以在超时的情况下调用HttpListener.GetContext
本文关键字:情况下 调用 HttpListener GetContext 超时 是否 | 更新日期: 2023-09-27 18:23:56
根据HttpListener引用,对HttpListener.GetContext的调用将被阻止,直到它从客户端获得HTTP请求。
我想知道我是否可以指定一个超时,以便在超时后函数将返回。我认为否则是不合理的,因为你不能保证会有一个请求让这个函数返回,那么怎么能终止这个调用呢?
附言:我知道它有一个异步版本(BeginGetContext),但问题仍然存在,因为相应的EndGetContext将阻塞,直到HTTP请求到达。
因此,总会有一个线程(如果你是多线程的)无法返回,因为它在等待请求时被阻止了。
我遗漏了什么吗?
更新:
我发现这个链接很有用。我还发现调用HttpListener.Close()实际上会终止BeginGetContext()创建的等待线程。不知何故,HttpListener.Close()会触发BeginGetContext()注册的回调。因此,在执行HttpListener.EndGetContext()之前,请检查HttpListener是否已停止。
此外,如果您想在进程中逐行等待有限的时间,BeginGetContext将返回一个System.IAsyncResult,暴露AsyncWaitHandle属性
var context = listener.BeginGetContext(new AsyncCallback(ListenerCallback), listener);
context.AsyncWaitHandle.WaitOne();
Above阻塞线程,直到侦听器接收到由分配给侦听器的heders定义的有效内容,或者由于终止侦听器线程并将结果返回给ListenerCallback的某个异常而终止。
但是AsyncWaitHandle.WaitOne()可以使用超时参数
// 5 seconds timeout
bool success = context.AsyncWaitHandle.WaitOne(5000, true);
if (success == false)
{
throw new Exception("Timeout waiting for http request.");
}
ListenerCallback可能包含对listener的调用。EndGetContext,或者只调用侦听器。如果AsyncWaitHandle 没有指示超时或错误,则行中的EndGetContext
public static void ListenerCallback(IAsyncResult result)
{
HttpListener listener = (HttpListener) result.AsyncState;
// Use EndGetContext to complete the asynchronous operation.
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerRequest request = context.Request;
// Get response object.
HttpListenerResponse response = context.Response;
// Construct a response.
string responseString = "<HTML><BODY> It Works!</BODY></HTML>";
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseString);
// Write to response stream.
response.ContentLength64 = buffer.Length;
System.IO.Stream output = response.OutputStream;
output.Write(buffer,0,buffer.Length);
// Close the output stream.
output.Close();
}
不要忘记告诉听众使用listener再次收听。BeginGetContext
调用EndGetContext的回调永远不应该被调用,除非HTTP请求已经到达,或者侦听器失败(在这种情况下,EndGetContext将抛出异常)。因此,如果使用得当,它不会阻塞。
BeginGetContext和EndGetContext——也就是异步操作——就是您想要的。
Begin和End方法的工作原理是,Begin说"X准备好时给我发信号",End说"给我你刚刚给我发过信号的X。"自然,后者在理论上会阻塞,但会立即返回。