Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C# AsyncCallback creates a new thread?

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

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

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.

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

That line 190 in diagnostics module is as follows:

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

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:

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?

Interpreting Visually:

enter image description here

like image 446
Mahesha999 Avatar asked Jan 09 '14 09:01

Mahesha999


People also ask

What does %d do in C?

%d is a format specifier, used in C Language. Now a format specifier is indicated by a % (percentage symbol) before the letter describing it. In simple words, a format specifier tells us the type of data to store and print. Now, %d represents the signed decimal integer.

What does -> mean in C?

An Arrow operator in C/C++ allows to access elements in Structures and Unions. It is used with a pointer variable pointing to a structure or union.

What is && operator in C?

The && (logical AND) operator indicates whether both operands are true. If both operands have nonzero values, the result has the value 1 . Otherwise, the result has the value 0 . The type of the result is int . Both operands must have an arithmetic or pointer type.


1 Answers

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

  • BeginXxx() starts a thread to get the job done, that thread makes the callback
  • BeginXxx() asks the operating system to get job done, using an I/O completion port to ask to be notified when it is done. The OS starts a thread to deliver the notification, that runs the callback.

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.

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.

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.

like image 191
Hans Passant Avatar answered Oct 07 '22 04:10

Hans Passant