c# - HttpClient.SendAsync using the thread-pool instead of async IO? -


So I am implementing via HttpClient.SendAsync reflectors. The intention that I wanted to know knowingly was the flow of execution of these methods, and to determine which API is called to perform asynchronous IO work.

HttpClient , I saw that internally it uses the HTTP client handler which is obtained from the HTTP Message Handler And its SendAsync method applies.

This implementation of HttpClientHandler.SendAsync :

Protected internal override work & lt; HttpResponseMessage & gt; SendAsync (HttpRequestMessage request, cancellation token cancellation token) {If (request == blank) {New argument NullException ("Request", SR.net_http_handler_norequest); } This.CheckDisposed (); This.SetOperationStarted (); TaskCompletionSource & LT; HttpResponseMessage & gt; Source = new task end source & lt; HTTPPRPS messages & gt; (); RequestState state = new requeststate {tcs = source, cancellation token = cancellation token, request message = request}; Try {HttpWebRequest request2 = this.CreateAndPrepareWebRequest (request); State.webRequest = request2; Cancellation Token. Registration (On-Dec, Request 2); If (execution consort. ISF flow suppressed ()) {IWebProxy proxy = faucet; If (this.useProxy) {Proxy = this.proxy ?? WebRequest.DefaultWebProxy; } If ((Use this. Default credentials || (this. Credentials! = Empty)) ((Proxy! = Null) & amp; (Proxy. Credentials! = Null)) {This Safe Capture Identity (state); }} Tasks. Factor Startup (this. Initial request, state); } Hold (exception exception) {this.HandleAsyncException (state, exception); } Return source. Task; }

What makes me feel that the above uses Task Factor When executing the request while preparing a code to start new , & quot; TaskCompletionSource & lt; HttpResponseMessage & gt; and work created by it.

Why do I feel this strange? Well, we learn a lot about how I / O bound asynchronous operation does not require extra thread behind the curtain, and how it all overlaps about it

Why is it a < Using the Task.Factory.StartNew to fire async I / O operation? This means that SendAsync is not using pure async control flow only to execute this method, but to perform its work, the Threadpool Thread "Behind Us" is spinning.

StartRequest is a representative that uses StartRequest which in turn replaces the HTTP WebRequest.BeginGetResponse async IO http client Under the cover, Async is using IO, which only wraps in a thread-pool task.

That said, note the following:

  // BeginGetResponse / BeginGetRequestStream in Async // (proxy, DNS, connection pooling, etc.) Does. Run them on different threads // Do not provide cancellation tokens; If this subsidiary can be canceled before starting, then // will not complete any TCS. Work. Factor Start (startup, state);  

There is a flaw in this API. HTTP client avoids blocking by moving that DNS task to thread-pool.

Is it good or bad? This is good because it blocks non-blocking the HTTP client and makes it suitable for use in the UI. This is bad because now we are using a thread for long lasting blocking work, although we had no hope of using threads to reduce the benefits of using async IO.

Actually, this is a good example of mixing sync and asyn Io, there is nothing wrong in using both. HttpClient and HttpWebRequest are using async IO for long-running blocking operations (HTTP requests). They are using thread for short-running tasks (DNS, ...). This is not a bad pattern normally, we are avoiding blocking most and we just have to make a small part of the code async. It is not good to find such things in a typical 80-20 trade-of-BCL (a library), but in the application level code that can be very smart trade-off.

It seems that it is better to fix http webbat . It is possible that compatibility is not possible for reasons.


Comments

Popular posts from this blog

java - org.apache.http.ProtocolException: Target host is not specified -

java - Gradle dependencies: compile project by relative path -

ruby on rails - Object doesn't support #inspect when used with .include -