13

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.

6
  • 4
    The new async / await pattern does not offer multithreading. It just offers cleaner code for handling operations that block your current thread. Commented Mar 7, 2013 at 14:56
  • The keywords do not mean, "use all my cores". They just tell the compiler and the runtime that an operation can be performed on a sperate thread. If there a 4 operations that may be run concurrently they might be run on 4 different cores. Commented Mar 7, 2013 at 15:01
  • You want to take a look at this asynchrony vs concurrency, async await DOES NOT help with multithreading. Its useful for even single cored machines. Commented Mar 7, 2013 at 15:05
  • Ok. So in other words - don't use async/await for multithreding. I get it now. Thank you. Commented Mar 7, 2013 at 15:17
  • 2
    You can most certainly use await in conjunction with multi-threaded code, you just need some mechanism to start running code in another thread, once you've done that through some other means, async/await can help you manage them more effectively. Commented Mar 7, 2013 at 15:20

1 Answer 1

18

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); 
Sign up to request clarification or add additional context in comments.

5 Comments

Alternatively, use the Parallel class, which is designed for parallel processing.
@StephenCleary the issue there is that the parallel methods block until the results are done, so you end up needing to throw the Parallel.For or Foreach into a Task.Run if you are currently in, say, a UI context and can't block until the tasks complete.
@Servy: True. But the benefit of Parallel is it will automatically partition work to make the best use of your available cores. As you said, you can wrap it in Task.Run to get a Task representing parallel work.
If from one of the Task.Run(() => myFunction()); I have a myFunction() returning some value, how do I handle it?
@codeln Have a List<Task<T>> and store the result of await Task.Whenall in a variable.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.