48

I have a large file which I have to send to a web api client...The data is multi part. The issue is , if the file is sent over http web request, then it is uploaded quickly on the webapi. For this request, file contents are written over the request stream directly.

Where as if the same file is sent over Httpclient (.net 4.5), the upload is slow when compared to http web request. I am using multipartformdatacontent in Httpclient post async.

So, for large files, do we have to use only web request? or is there any settings on Httpclient that makes the upload faster?

4
  • 1
    HttpWebREquest models a single request. HttpClient models, well, a client--something that makes multiple requests. HttpClient is much more recent, so more likely to have up-to-date knowledge. Although, I don't know if it's specifically faster in certain areas; but certainly more recommended if you're doing anything in the WebAPI space or REST. Commented Mar 6, 2014 at 19:28
  • 4
    HttpClient uses HttpWebRequest under the covers to actually make the HTTP request, so you should be able to get the same performance. Commented Mar 7, 2014 at 15:40
  • 1
    yes..but again the performance depends on how the content is passed through the client.. I used FileStreamContent and now I had changed to ByteArrayContent... Commented Mar 9, 2014 at 0:18
  • HttpWebRequest is obsolete, case closed: SYSLIB9914: 'WebRequest.Create(string)' is obsolete: 'WebRequest, HttpWebRequest, ServicePoint, and WebClient are obsolete. Use HttpClient instead.' Commented Sep 17, 2022 at 2:18

3 Answers 3

51

HttpClient is more like a head-less browser. It a powerfull and ideal tool if you are going to be creating many http request. For example you can set default headers and stuff. Here are the top 5 ways it differs from an HttpWebRequest which is taken from here

  1. An HttpClient instance is the place to configure extensions, set default headers, cancel outstanding requests and more.
  2. You can issue as many requests as you like through a single HttpClient instance.
  3. HttpClients are not tied to particular HTTP server or host; you can submit any HTTP request using the same HttpClient instance.
  4. You can derive from HttpClient to create specialized clients for particular sites or patterns
  5. HttpClient uses the new Task-oriented pattern for handling asynchronous requests making it dramatically easier to manage and coordinate multiple outstanding requests.
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks. This doesnt answer my question. I have an await on postAsync method and even that doesnt help. Am wondering how webrequest is faster when compared with httpclient?
Attribution is normally recommended: blogs.msdn.com/b/henrikn/archive/2012/02/11/…
Attribution twice in the post and another time in comments is quite funny... :-)
Great answer. The first 7 words alone could solve many of the "why can't I scrape xyz.com using HttpClient?"
The resource in the link uses JsonArray which does not seem to be available
5

I was using FileStreamContent with httpclient...But when I used ByteArrayContent, it worked fine.

I am not sure how and why this made the difference, but sending bytes over the stream is a better way rather than sending the stream

4 Comments

Where did you get FileStreamContent? That isn't a default in-the-box HttpContent implementation.
Nope. I'm pretty sure it is not in either of those.
my bad..it is the StreamContent I was talking about. msdn.microsoft.com/en-us/library/…
Showing code snippets in the question, and in this answer, would be helpful. I speculate that your byte array is significantly larger than the default stream buffer, and this helped httpclient send it with less overhead.
5

Perhaps you were instantiating HttpClient in a using block which could explain performance issues. E.g.

  using (var httpClient = new HttpClient() )
  {
      var result = await httpClient.GetAsync("http://example.com");
      Console.WriteLine(result.StatusCode);
  }

Here the instance of HttpClient is being disposed immediately after the request whereas it should arguably be a long lived object (E.g. the lifetime of the application).

[edit - added context]

Disposing the instance also closes the connection but leaves the socket in a waiting state for a set duration. For each execution of this code, the os will attempt to create a new socket connection, and since there is a limit to how quickly this can be completed, performance/reliability issues can arise.

Reusing the same HttpClient instance means better reuse of open sockets and more efficient use of system resources.

More info here.

8 Comments

CS4033: "The 'await' operator can only be used within an async method. Consider marking this method with the 'async' modifier and changing it's return type to 'Task'." So, what does the method declaration surrounding this code look like, and what is the valid Task<T> value that you used in the corresponding return statement? 🤔🤨
@NetXpert I think you’ve missed the point. This code block is simply to illustrate how httpclient might be misused by instantiating it in a using block. Wrapping it in a method definition adds nothing of value. Also, the OP states .Net 4.5 as the target.
I think you missed the larger point: Given that the code you've given won't even compile, I think that you've completely lost the forest in the trees! It's pretty difficult, in my experience, to somehow inadvertently mis-use code that can't even be used in the first place due to not being compilable because of the errors I identified...
"Also, the OP states .Net 4.5 as the target" -- that's why I specifically added the comment "This is not an example of contemporary, valid code." -- so future readers of this post would see a note pointing out that it's not valid C# anymore.
@NetXpert The code sample compiles and runs fine. 1. Create a C# console program. target .net framework 4.5. 2. Import System.Net.Http from nuget. 3. Add an async method (E.g. public static Task DoStuff) and paste my code in its body, changing 'example.com' to the url you'd like to spam, and call it from your main method*. 4. Build it and run it. StatusCode is indeed a property of System.Net.Http.HttpResponseMessage after GetAsync is 'await'ed. * If you need help creating/calling an async method, ask a question on SO and I'm sure someone will be willing to help you.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.