Does c # async work single-threaded?

I read http://msdn.microsoft.com/en-US/library/vstudio/hh191443.aspx . Code example:

async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); // You can do work here that doesn't rely on the string from GetStringAsync. DoIndependentWork(); // The await operator suspends AccessTheWebAsync. // - AccessTheWebAsync can't continue until getStringTask is complete. // - Meanwhile, control returns to the caller of AccessTheWebAsync. // - Control resumes here when getStringTask is complete. // - The await operator then retrieves the string result from getStringTask. string urlContents = await getStringTask; // The return statement specifies an integer result. // Any methods that are awaiting AccessTheWebAsync retrieve the length value. return urlContents.Length; } 

The page also says:

Asynchronous and pending keywords do not create additional threads. Asynchronous methods do not require multithreading, because the async method does not start in its thread

Is this "extra thread" created as part of a method marked async?

I would suggest that both GetStringAsync and AccessTheWebAsync will work at the same time (otherwise GetStringAsync will never end, since AccessTheWebAsync now has control), ultimately GetStringAsync should work in a different thread from the AccessTheWebAsync thread.

It’s useful for me to write the async method only when adding more threads, when the method that it expects is also asynchronous (which already uses an additional thread for parallel operation)

Do I understand correctly?

+6
source share
4 answers

This is the key to async power. GetStringAsync and other naturally-asynchronous operations do not require a thread. GetStringAsync simply sends an HTTP request and registers a callback to start when the server responds. There is no need for a thread to wait for a server response.

In reality, the thread pool is used only a little. In the above example, the callback registered by GetStringAsync will be executed in the thread pool thread, but all it does is notify AccessTheWebAsync that it can continue to execute.

I have an async intro blog post that you might find useful.

+12
source

I would suggest that for GetStringAsync and AccessTheWebAsync would work at the same time ...

They do not work at the same time (at least not in the way you think). Now if HttpClient.GetStringAsync itself

  • started working with another thread, then this code could work at the same time, -or-
  • It was expected (with ConfigureAwait (false)), then the rest of the work in this method would be planned in the thread pool thread (and so that the code could work simultaneously).

The fact is that declaring a method as async and / or using await does not cause the method you create to run in a separate thread (you will need to do this explicitly).

Note: Without the code (or documentation) of another asynchronous method, you do not know how much of it runs synchronously. In fact, it does not start to be asynchronous until this method executes await or explicitly starts work on another thread (usually by starting a new Task )

+1
source

There is a thread that is taken from the thread pool for the operation, if necessary. In the case of the console (without discussing UI threads or IO threads), the current thread goes to the console, and another thread runs to execute, and this new thread is the one that performs the remaining operation.

0
source

What the author says here is that simply using async keywords and waiting does not cause the current method to run in another thread. Let's look at what happens in the provided code.

 async Task<int> AccessTheWebAsync() { // You need to add a reference to System.Net.Http to declare client. HttpClient client = new HttpClient(); // GetStringAsync returns a Task<string>. That means that when you await the // task you'll get a string (urlContents). Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com"); 

Everything up to this point has been running in a single thread. At this point, calling client.GetStringAsync can unscrew the new thread (although this is not guaranteed for any async method). It should be noted, however, that the GetStringAsync method essentially starts this current thread (for example, it actually makes a call), but the response will be read in another thread after it returns. This is represented by returning a Task object. A task can be an already completed bit of work, a current executable secondary thread, or a block of work that is simply scheduled to be completed later.

 DoIndependentWork(); 

Now this is done in our main thread after the call has been queued (or possibly sent). Therefore, this can happen while waiting for a request to be returned. Please note that we are still in our main topic.

  string urlContents = await getStringTask; 

At this point, our thread returns ..NET will create a continuation function containing the rest of the method (return urlContents.Length;), which will be automatically called for us as soon as getStringTask completes its own thread. At this point, the new thread will pick up a sequel.

Thanks to all this, everything that we wrote in our async method, up to the wait keyword, was performed in one thread. Of course, we called another method that could happen to create another thread, but we did nothing to create another thread, just using the async / await keywords. The continuation at the end can be called, perhaps, another thread, but after our initial function really returned (that’s why our function returns a Task object to represent work that may not finish when any calls to this function return).

-3
source

Source: https://habr.com/ru/post/949784/


All Articles