Guillaume D
Guillaume D

Reputation: 185

Simple question about asynchronous programming

I have a simple question with async programming exposed by the following example:

foreach (var item in result)
{
    property1 = await GetObjectivesQueryable(ObjectiveType.Company, from, to).SumAsync(x => x.ValeurObjectif);
    property2 = await GetObjectivesQueryable(ObjectiveType.Company, new DateTime(DateTime.Now.Year, 1, 1), new DateTime(DateTime.Now.Year, 12, DateTime.DaysInMonth(DateTime.Now.Year, 12)).AddHours(23).AddMinutes(59).AddSeconds(59)).SumAsync(x => x.ValeurObjectif);
}

or the alternative:

foreach (var item in result)
{
    var task1 = GetObjectivesQueryable(ObjectiveType.Company, from, to).SumAsync(x => x.ValeurObjectif);
    var task2 = GetObjectivesQueryable(ObjectiveType.Company, new DateTime(DateTime.Now.Year, 1, 1), new DateTime(DateTime.Now.Year, 12, DateTime.DaysInMonth(DateTime.Now.Year, 12)).AddHours(23).AddMinutes(59).AddSeconds(59)).SumAsync(x => x.ValeurObjectif);

    await Task.WhenAll(task1, task2);

    property1 = task1.Result;
    property2 = task2.Result;
}

From what i understand about async programming the first example above will execute the first instruction, block the execution thread until it complete with the await keyword then fill the property. Then redoing this step for the second property.

At the opposite the second example will asynchronously execute the both task and block the execution thread during the WhenAll instruction, then when both of the tasks are completed it will synchronously set property 1 and property 2.

So From my conclusion in this use case the second example is more performing.

Do my knowledge about async in this case is right?

Thanks in advance.

Upvotes: 4

Views: 264

Answers (2)

tmaj
tmaj

Reputation: 35037

Despite being imprecise about the thread being blocked (which is incorrect as pointed out in the comments), you are correct.

While 'more performing' may mean many things, assuming that both operations are independent, Task.WhenAll option will finish earlier.

Having

var work1 = async () => await Task.Delay(1000);
var work2 = async () => await Task.Delay(2000);
await work1();
await work2();

will take 3 seconds, and

await Task.WhenAll(work1(), work2());

will take 2 seconds.

Upvotes: 1

Amogh Sarpotdar
Amogh Sarpotdar

Reputation: 617

First point I would suggest is to differentiate between multithreading and multiprocessing. Read here https://towardsdatascience.com/multithreading-and-multiprocessing-in-10-minutes-20d9b3c6a867 to understand more about it.

You are using language provided constructs to make it possible for the OS to process two units of work in parallel. Please do not call it multi-threading, although it is relevant it implies you are in control of lot more factors than you can in parallel processing constructs like async and await. In fact, this is why we still have explicit constructs for threading present in c#, such as BackgroundWorkerThread, despite of success of async and await.

Largely your understanding is correct. However it becomes accurate when you put underlying hardware into picture.

Modern processors have multiple cores. Which means it is much more convenient to have parallelly running units of work. When you write your code using async and await, not necessarily it is going to get processed in parallel. It depends upon lots of other factors including operating system's state, number of threads in the pool, available cores that can pick up subsequent task, other processes running in parallel etc.

If you run async code on a processor which has only one core available for processing, effectively you are running blocking code since there is simply now way to have multiple instructions run in parallel without incurring cost of suspending one thread and loading another into memory - it might in fact become much slower than a simple blocking code that does not require context switching.

With async and await you are simply paving way for multiprocessing if everything else aligns. In most of the circumstances it does, but it has limits.

Take a look at https://learn.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-max-degree-of-parallelism-server-configuration-option?view=sql-server-ver16 to understand about maximum degree of parallelism.

Also, this is not a new concept. Its the c# language construct that abstracts away underlying complexity, without having you to do it - thats the key aspect of async and await.

Upvotes: 0

Related Questions