c# - C# AsyncCallback 是否创建一个新线程?

标签 c# .net multithreading http asynchronous

我写了一个 HttpListener 监听其中一个端口:

httpListener.BeginGetContext(new AsyncCallback(ListenerCallback), httpListener);

ListenerCallback 处理在监听器 uri 上收到的任何请求。如果在处理请求期间发生异常,它会运行一个诊断例程,该例程会尝试访问监听器 uri,以检查监听器是否实际上处于事件状态并正在监听 uri 并写入监听器返回的响应日志。 Listener 简单地返回字符串 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 分派(dispatch)新线程并在该新线程中运行 ListenerCallback,则在发送虚拟请求时不得导致 Operation Timeout通过诊断。这就是我认为所需的行为应该是因为它是 *Async*Callback。其实MSDN也有says the same :

Use an AsyncCallback delegate to process the results of an asynchronous operation in a separate thread.

但似乎并非如此。我在这里错过了什么吗?

视觉解释:

enter image description here

最佳答案

它完全是类的 BeginXxx() 方法的实现细节。有两种基本方案:

  • BeginXxx() 启动一个线程来完成工作,该线程进行回调
  • BeginXxx() 要求操作系统完成工作,使用 I/O 完成端口要求在完成时得到通知。操作系统启动一个线程来传递通知,该线程运行回调。

第二种方法非常可取,它可以很好地扩展程序能够有许多 挂起的操作。并且是 HttpListener 使用的方法,Windows 上的 TCP/IP 驱动程序堆栈支持完成端口。您的程序可以轻松支持数千套接字,这在服务器场景中很重要。

回调中的 EndXxx() 调用报告在尝试通过抛出异常来完成 I/O 请求时遇到的任何错误。在您的情况下, BeginGetContext() 需要回调中的 EndGetContext() 。如果您没有捕获异常,那么您的程序将终止。

您的代码片段实际上并未演示任何异步 I/O。您调用了 GetResponse() 而不是 BeginGetResponse()。根本不涉及回调,因此失败并引发异常的是 GetResponse() 方法。

关于c# - C# AsyncCallback 是否创建一个新线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21015746/

相关文章:

c# - "unhandy"字典的JSON反序列化

c# - EF7 .NET Core 1 RC2 添加迁移失败

c# - 如何在没有用户交互的情况下在 ASP.NET 中启动任务

c++ - 如何将类中的函数放入线程中? (使用 Boost 的 C++)

android - 如何每 2 秒在两个值之间连续切换文本切换器

c# - 在 ASP.NET 中设置动态创建图像的内容长度

c# - 与 xp 上的 2010 相比,找不到引用的组件 'vbide'

.net - "SAP Function OCX"的使用

c# - 使用记录器记录堆栈跟踪

java - 同一线程上的代码以异常顺序执行