What is a strict definition of what should be the "expected" task?

I am trying to understand async - await at a deep level. Whenever I see examples of how this works, the example uses the await method, which is called LongRunningTask or similar, and it has Task.Delay or new WebClient().Download("http://google.com") or something like that. I am trying to understand that there will be a strict definition of what to expect. This cannot be just a β€œlong-term task” because a long-term task can be something like finding the maximum array sub-array of size 1,000,000,000, which does not bring any performance benefits await ed on if it is true that async - await does not create any new threads.

From what I understand, if you have something like

 var task = LongRunningTask(); DoSomething(); int x = DoSomethingElse(); int y = await task; int z = x + y; 

then a piece

 DoSomething(); int x = DoSomethingElse(); 

is what you are hinting at a compiler that

"Hey compiler, if you can make sure this piece has no dependencies on LongRunningTask and vice versa, then you can start dividing your work between LongRunningTask and this piece of code. You haven't finished LongRunningTask by the time you finish this piece of code and then just work on completing the LongRunningTask , so why am I telling you await it. "

Can you help straighten me?

+6
source share
3 answers

await less magical than you think. In your example, the decision about whether to use other threads, or I / O completion procedures, etc., is not specified in any of the code that you specified.

The LongRunningTask implementation, being a method that returns an already running Task , makes any difficult decisions about how and when this Task will be completed.

All await does is wait (as the name suggests) for what has already been launched.

Now , if LongRunningTask is implemented by creating new Jobs, and these tasks use the default scheduler that uses this thread pool, and if your current method is already running in the thread pool thread and some of the tasks created by LongRunningTask expect the thread pool thread to become available, then it is possible that the very thread that executed your code becomes available when await is encountered and will be used to start one of the pending tasks. But that’s basically what you don’t need to think about.

+5
source

For the purposes of your question, a long-term task is any task that includes input / output (input-output).

This is a class of excellent tasks that can be expected because what usually happens with I / O is that the computer issues instructions to start I / O and then just waits (usually in a low processor state) for input / output.

So, new WebClient().Download("http://google.com") is a good example of a task that includes I / O, because to complete this task, the machine will need to prepare a request for google.com, start send it on the socket, wait for the request to be completely sent, wait for the answer to start arriving, and then wait until the answer is fully reached.

However, this definition is not strict; even if you find the maximum subarray of an array of 1,000,000,000 in size it can be a long-term task if it was implemented by creating a new stream, because if we are talking about the calling stream, we will have a very similar scenario: (create a new stream by passing it an array to search for) and then wait for the results without doing anything.

Edit

In light of the above, the example with the maximum subarray of a huge array can be considered as a red herring, because in order to wait for asynchrony, the question of whether this is or is not a long-term task depends on whether it is launched in a separate thread or not.

Thus, a much better definition of a long-term task could be:

Any task that takes such an amount of time to complete it is undesirable to block waiting in the current executable thread.

So, for example, if you are writing an interactive application (GUI) and want to guarantee a response time in milliseconds to your human user, then any task that should take more time is a long-term task: you run it, wait for it, and while it works, your GUI is still responsive. On the other hand, if you are writing a batch processing task that is designed to work overnight to crunch some big data, then almost no task should be considered a long-term task.

+1
source

As indicated in the answer above, Task CAN starts different threads and waits for the wait result for these specific tasks.

Usually tasks, such as API calls, that are completely independent of processing power, i.e. even if you have maximum RAM, the processor has no or little effect on your response, i.e. I / O delay time, which is the task to be performed. And these tasks are internally completed by a thread of work and are usually expected

Link: Essential C # 6.0 (5th Edition)

0
source

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


All Articles