async i/o completion routines, threading question

M

Mark

Hi...

We've tried to implement the jabber xep-0124 http tunneling extension using
the HttpListener class on the server side (basically other jabber
conversations get wrapped in an http request, and the connection gets kept
open with 1 request outstanding all the time).

We've also tried to implement a test harness in C# with buckets of async i/o
completions and callback delegates. Looking over the test harness, there are
some interesting questions I'm scratching my head about:

1) Each tester uses System.Net.WebRequest.Create (url) to initiate a contact
and the BeginGetResponse() method to asynchronously wait for the response.
Request.KeepAlive is set to false. The initial WebRequest.Create(url) takes
a long time (~ 13 seconds) to get a connection to the destination server but
subsequent message sends are generally much faster. With KeepAlive set to
false, is the framework keeping the connection open anyway? Is it keeping
some of the info cached? I'm wondering why subsequent
WebRequest.Create(url)s get the request sent so much more quickly than the
initial one.

2) As part of processing the conversation on the tester side, it reads from
the response with async completion. When there is no more to read, the
completion function parses the xml returned and loops through the data
returned. As part of processing the return data, new requests can be
initiated. It's in one of these, that things seem to get synchronous again.

There's only 1 part of the conversation that's not initiated from the client
side. Usually it's client sends A and expects response B. But in the jabber
authentication phase, client sends credentials and the server respond with
success, *then* the server asks the client a question (what protocol level is
supported). The server's question comes in the next response going to the
client.

The conversation looks something like this:
Client connect-> Server
Client <- connid Server

Client login -> Server
Client <- success Server

Client directory request -> Server
Client <- version request Server
Client <- directory listing Server (both in same http response)

Client version resp -> Server
(server has no answer to this, so it waits to timeout).

The thing I'm having trouble figuring out is that double-response. My i/o
completion callback gets both answers and processes the version request
first. This results in sending the version response - which *should* also be
asynch, but what I'm seeing is that my callback doesn't go ahead to process
the 2nd part of the packet until after the version response call times out.
It's like I'm only allowed to be processing 1 async completion callback at a
time.

Can anyone shed any light on that?

Thanks
Mark
 
S

Steven Cheng

Hi Mark,

I'll try to answer the questions about .NET network components you
mentioned:

#1 Yes, .NET framework has added an additional layer(like a connection
pool) for each process. Therefore, the WebRequest or other component you
hold is not representing a physical connection, but the underlying
ServicePointManager will help arrange the phyiscal ones(such as reuse
them). Here is a good blog article explain this:

#Understanding System.Net Connection Management and ServicepointManager
http://blogs.msdn.com/adarshk/pages/345411.aspx

For the #2 issue you mentioned, I think it maybe due to the default 2
connection limitation of .NET process. By default, each .NET process will
be limited to establish only two connections to a given remote server.
Thus, in cases(such as in your environment), if the two connection has been
already occupied, the further connection attemp should be pending util one
of them is released. Here is also an article explain this:

#Connection Groups and Connection Limits
http://blogs.msdn.com/mflasko/archive/2005/09/11/463865.aspx

You may try enlarging the value to see whether it helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead



==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.



Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.


--------------------
From: =?Utf-8?B?TWFyaw==?= <[email protected]>
Subject: async i/o completion routines, threading question
Date: Wed, 27 Feb 2008 14:52:00 -0800
 
M

Mark

Hi Steven...

Thank you for those links. They were very helpful. The answer to problem
#2 I found in a comment on the first blog entry. The MSDN page for
WebRequest.BeginGetRequestStream has a Note: on it that says you must use
either the synchronous or async versions for both GetRequestStream and
GetResponse; you can't mix and match. Unfortunately, it doesn't say what
would happen if you *did* mix them.

Our code was using GetRequestStream() to post the request synchronously,
then attempting to read the response asynchronously. Apparently when you do
that, the asynch calls for BeginGetResponse() don't fail - they're just
executed synchronously. I only saw the note on BeginGetRequestStream() and
it was too vague about what would happen to code from.

Even with all the documentation and blog entries, I'm still a little bemused
by several things in question #1.

a) The two servers in question are in the same building on the same net; 13
seconds seems a long time to open a connection between them on the first
call. I have both client and server logging and it's 13 seconds between when
the client does a WebRequest.Create() and writes the post to the time the
server logs receiving it. I'm just not clear on whether the time is being
chewed up in the ServicePointManager on the client side or in the
HttpListener stuff on the server side, but 13 seconds to open a connection
seems unnecessarily long.

b) From everything I've seen, the fact that our client is setting
HttpWebRequest.KeepAlive = false should have resulted in the connection
being closed. But the fact that subsequent requests don't take 13 seconds
each makes me think that they're not. My HttpListener on the server side
isn't paying attention to the KeepAlive header and just keeps the connection
open; is the HttpWebRequest.KeepAlive property mostly effected by the server
side? I.e. setting this property on HttpWebRequest gets the http header
sent, but it's up to the http server side to respect it?

Thanks
Mark
 
H

Henning Krause [MVP - Exchange]

Hello,

AFAIK the WebRequest tries to detect a proxy on it's first run. That's why
you are seeing this initial delay.

Kind regards,
Henning Krause
 
M

Mark

Thanks, Henning... That was it. The documentation on HttpWebRequest.Proxy
appears out-of-date (apparently the old way of specifying no proxy is
deprecated) but explicitly setting no proxy was a huge help.

Mark
 
S

Steven Cheng

Thanks for Henning's sharing.

That really get the point.

BTW, for the MSDN document reference getting out-of-date issue, I suggest
you submit it to the product feedback center:

http://connect.microsoft.com/feedback/default.aspx?SiteID=210

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.


-------------------------------
From: =?Utf-8?B?TWFyaw==?= <[email protected]>
References: <[email protected]>
<[email protected]>
Subject: Re: async i/o completion routines, threading question
Date: Fri, 29 Feb 2008 10:28:06 -0800
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top