Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing multithreaded methods using async/await in .Net 4.5

I have a small query.

I admit that I haven't use multithreading much before .Net 4.5, but with the new async/await functionality I decided to give it a try. I started experimenting with it and all seems fine, but I wasn't able to find a solution for my "problem" anywhere on the web.

So everyone explain how await can be used with the newly transformed methods of the .Net platform (e.g. WriteAsync(), ReadAsync() etc...), but what if I wanted to use it for my own methods? For example, lets say that I am performing an extremely expensive calculation and want all of my 4 cores working on it. I would have something similar to this:

async Task DoLotsOfWork<T>(T[] data, int start, int end)
{
    //Do very expensive work
}

But since I don't have an await keyword there, the method is just treated as a synchronous one. I would like to call it 4 times from outside so that it can run on all of my cores, while I display something sensible to the user(e.g. "Please wait..."). The only solution that I was able to figure out was to add a await Task.Yield(); in the start of the method. Something like this:

async Task DoLotsOfWork<T>(T[] data, int start, int end)
{
    await Task.Yield();
    //Do very expensive work
}

In that case, the method would behave as I would expect it to. But is there a better solution for this? I feel that it should be easier/more sensible than writing exactly that line of code. I understand that I can create a Task/Thread object and call the Start() method, but that requires even more work. I just thought that with the new async/await functionality this sort of thing would be easier.

like image 781
Milcho Avatar asked Mar 07 '13 14:03

Milcho


People also ask

Can we use async await in foreach C#?

C# 8 the next major release of the C# language will include Asynchronous Streams. Using this new feature you will be able to apply the await keyword directly to your foreach loops!

What is the difference between async await and thread C#?

Threads. Async methods are intended to be non-blocking operations. An await expression in an async method doesn't block the current thread while the awaited task is running. Instead, the expression signs up the rest of the method as a continuation and returns control to the caller of the async method.

Is async await multithreaded?

The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.

Does async await block main thread C#?

The await operator doesn't block the thread that evaluates the async method. When the await operator suspends the enclosing async method, the control returns to the caller of the method.


1 Answers

So to start with you'll need a method that does the very expensive work synchronously:

public void DoLotsOfWork<T>(T[] data, int start, int end) 
{
    Thread.Sleep(5000);//placeholder for real work
}

Then we can use Task.Run to start multiple instances of this work in a threadpool thread.

List<Task> tasks = new List<Task>();
for(int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(()=>DoLotsOfWork(data, start, end));
}

Then we can do a non-blocking wait until all of them are done:

await Task.WhenAll(tasks);
like image 113
Servy Avatar answered Oct 24 '22 21:10

Servy