【发布时间】:2014-01-27 17:45:12
【问题描述】:
我写了一个HttpListener,它监听其中一个端口:
httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpListener);
ListenerCallback 处理在侦听器 uri 上收到的任何请求。如果在处理请求期间发生异常,它会运行一个诊断例程,该例程会尝试访问侦听器 uri,以检查侦听器是否实际上是活动的并正在侦听 uri,并写入侦听器返回的响应日志。侦听器只是将字符串 Listening... 返回到此类虚拟请求。
现在在测试过程中,当其他模块发生异常导致执行诊断模块时,我可以看到侦听器在检查日志时正确返回了Listening...。
但是,当ListenerCallback 中发生异常时,尝试在诊断中访问侦听器 URI 时会引发以下异常:
System.Net.WebException : The operation has timed out
at System.Net.HttpWebRequest.GetResponse()
at MyPackage.Diagnostics.hitListenerUrl(String url) in c:\SW\MyApp\MyProj\Diagnostics.cs:line 190
诊断模块第190行如下:
189 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
190 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
现在,如果AsyncCallback 调度新线程并在该新线程中运行ListenerCallback,则当通过诊断发送虚拟请求时,它一定不会导致Operation Timeout。这就是我认为应有的行为,因为它是*Async*Callback。其实MSDN也有says the same:
使用 AsyncCallback 委托在单独的线程中处理异步操作的结果。
但似乎并非如此。我在这里错过了什么吗?
视觉解读:
【问题讨论】:
-
“通过诊断发送虚拟请求”完全不清楚。看来您是在问自己的理论,这很可能是错误的。
-
@HenkHolterman 我已将诊断的第 190 行放在了显示我如何向侦听器 uri 发送请求的位置。
-
所以一个崩溃的监听器停止监听...
-
是的,不会完全停止侦听而是很忙,因为诊断仅在侦听器线程中运行,如果
ListenerCallback不在新线程上执行,则请求通过@987654337 发送到uri @'s 线程的诊断永远不会得到任何响应。添加了图表,请检查。它记录Operation Timeout并退出诊断。但是由于ListenerCallback中的操作失败,另一个依赖线程(有一个循环)抛出异常并在每个循环中运行诊断。对于那些诊断ListenerCallback正确返回Listening... -
你一直提到一些“诊断”:那是什么?这是你的程序中的东西吗?
标签: c# .net multithreading http asynchronous