Writing multithreaded methods using async/await in .Net 4.5

.net, asynchronous, c#

Solution

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);

Problem

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.

Original source

Related problems