3

I'm wondering whether .Net HttpClient async method run in new threads or in the main one.

For example, In my Console Application, I invoke an async method to download a URL content using HttpClient.GetStringAsync method.

Will this method (GetStringAsync) run in new separate thread?

Mhd
  • 2,778
  • 5
  • 22
  • 59
  • 3
    I'd suggest you to read this question: http://stackoverflow.com/q/37419572/5311735 and answer to the end. In short - you cannot tell exactly without inspecting source code (or unless it's mentioned in documentaiton). – Evk Apr 05 '17 at 17:01

2 Answers2

9

In general, asynchronous I/O methods do not use separate threads. I explain this in detail in my blog post There Is No Thread.

However, in this specific case, that's not quite true. WebRequest-based APIs in .NET have supported asynchronous operations for a long time, but have actually always done HTTP proxy detection and DNS lookup as synchronous, even through their asynchronous APIs. This was noticed when HttpClient started becoming popular. Unfortunately, Microsoft decided not to fix these long-standing bugs.

So, HttpClient wraps its WebRequest calls in a thread pool thread. Note that it is still using the "asynchronous" APIs, so only the synchronous portion (HTTP proxy and DNS lookup) are done on a thread pool thread; the rest of the request is truly asynchronous. At least, this is true for some platforms.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • I was looking at this example https://msdn.microsoft.com/en-ca/library/mt674882.aspx . Luckily, there was HttpClient example. In that link, there is a section called Thread and they mentioned that no extra threads will be created within async-await context. Do you think that section is not related to the example? – Mhd Apr 05 '17 at 21:06
  • `The async and await keywords don't cause additional threads to be created.` - that statement is perfectly true. Neither `async` nor `await` create new threads. – Stephen Cleary Apr 05 '17 at 21:15
  • @StephenCleary - I'm surprised to hear .NET's own `GetStringAsync` actually IS NOT truly asynchronous... is it at least safe to assume most other .NET methods with `Async` in the name are truly asynchronous and not making threads? Such as File.WriteAsync. – Don Cheadle Jul 01 '18 at 21:26
  • @mmcrae: No. For `File` in particular, the I/O is not asynchronous unless an async flag is passed to the constructor. – Stephen Cleary Jul 01 '18 at 22:41
  • @StephenCleary sounds like async IO is not as enabled as I thought. I guess I am very surprised since I understood from your posts and others that most IO at least on Windows is truly async (no thread). And discussions saying to use async with all of the `...Async` methods in .NET. I thought a big point of `async / await` was to get access to the true asynchronous behavior that already exists through the framework and the hardware. – Don Cheadle Jul 01 '18 at 22:57
  • @mmcrae: Asynchronous Win32 APIs are all truly asynchronous. In the .NET world, it's not as clean. There's some weird quirks that can't be fixed due to backcompat (e.g., `HttpClient`), and other weird quirks due to OOP (e.g., what's the "correct" implementation of `MemoryStream.ReadAsync`?), and other weird quirks for AFAIK no good reason (e.g., `File` async I/O requiring a special flag to be truly asynchronous). – Stephen Cleary Jul 02 '18 at 02:34
0

No. Because using async / await is mainly created to accomplish IO-bound tasks asynchronously not creating new threads. Only with CPU bound tasks new threads are created.

DigheadsFerke
  • 307
  • 1
  • 8
  • Any links on proofs of this statement? – cassandrad Apr 05 '17 at 17:02
  • 1
    Programming in C# Exam Ref 70-483 – DigheadsFerke Apr 05 '17 at 17:12
  • @DigheadsFerke page? – cassandrad Apr 05 '17 at 17:20
  • 2
    Page 17: Asynchronous code solves this problem. Instead of blocking your thread until the I/O operation finishes, you get back a Task object that represents the result of the asynchronous operation. By setting a continuation on this Task, you can continue when the I/O is done. In the meantime, your thread is available for other work. When the I/O operation finishes, Windows notifies the runtime and the continuation Task is scheduled on the thread pool. – DigheadsFerke Apr 05 '17 at 17:28
  • Page 19: So doing a CPU-bound task is different from an I/O-bound task. CPU-bound tasks always use some thread to execute their work. An asynchronous I/O-bound task doesn’t use a thread until the I/O is finished. – DigheadsFerke Apr 05 '17 at 17:33