C#AsyncCallback是否创建了一个新线程? [英] Does C# AsyncCallback creates a new thread?

查看:672
本文介绍了C#AsyncCallback是否创建了一个新线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个 HttpListener ,它会侦听其中一个端口:

I have written an HttpListener which listens on one of the ports:

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

ListenerCallback 处理收到的任何请求听众uri。如果在处理请求期间发生异常,它将运行一个诊断例程,该例程尝试命中侦听器uri以检查侦听器是否实际处于活动状态并侦听uri并写入侦听器返回的响应日志。 Listener只是将字符串 Listening ... 返回给这样的虚拟请求。

The ListenerCallback handles any request that is received on the listener uri. If exception occurs during handling request, it runs a diagnostics routine, which tries to hit listener uri just to check if the listener is in fact alive and listening on the uri and writes the log of response returned by the listener. Listener simply returns string Listening... to such dummy requests.

现在在测试期间,当其他异常发生时导致执行诊断模块的模块,我可以看到监听器在检查日志时正确地返回 Listening ...
但是当 ListenerCallback 中发生异常时,尝试点击诊断内的侦听器URI会引发以下异常:

Now during testing, when exception occurred in other modules which resulted in the execution of the diagnostic modules, I can see the listener returned Listening... properly when I checked the logs. However when exception occurred in the ListenerCallback, the attempt to hit the listener URI inside diagnostics threw following exception:

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行如下:

That line 190 in diagnostics module is as follows:

189     HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
190     HttpWebResponse response = (HttpWebResponse)request.GetResponse();

现在如果 AsyncCallback 调度新线程并运行 ListenerCallback 在该新线程中,当通过诊断发送虚拟请求时,不得产生操作超时。这就是我认为理想的行为,因为它是 * Async * Callback 。事实上,MSDN也同样的说法

Now if AsyncCallback dispatches new thread and run ListenerCallback in that new thread, it must not result Operation Timeout when the dummy request is sent through the diagnostics. This is what I thought the desired behavior should be since it is *Async*Callback. In fact MSDN also says the same:


使用AsyncCallback委托在单独的线程中处理异步操作的结果。

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

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

But seems that is not the case. Am I missing something here?

以视觉方式解释:

推荐答案

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

It is entirely an implementation detail of the class' BeginXxx() method. There are two basic schemes:


  • BeginXxx()启动一个线程来完成工作,该线程进行回调

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

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

The second approach is very desirable, it scales well with the program being able to have many pending operations. And is the approach used by HttpListener, the TCP/IP driver stack on Windows supports completion ports. Your program can support thousands of sockets easily, important in server scenarios.

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

The EndXxx() call in the callback reports any mishaps encountered while trying to complete the I/O request by throwing an exception. In your case, the BeginGetContext() requires EndGetContext() in the callback. If you don't catch the exception then your program will terminate.

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

Your code snippet does not actually demonstrate any asynchronous I/O. You called GetResponse() instead of BeginGetResponse(). No callback is involved at all, it will thus be the GetResponse() method that fails and throws the exception.

这篇关于C#AsyncCallback是否创建了一个新线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆