Writing multi-threaded methods using async / wait in .Net 4.5

I have a small request.

I admit that I did not use multithreading much earlier .Net 4.5, but with the new async/await functionality I decided to give it a try. I started experimenting with him, and everything seems fine, but I could not find a solution to my "problem" anywhere on the Internet.

So everyone explains how await can be used with the newly formed .NET platform methods. (e.g. WriteAsync() , ReadAsync() , etc.), but what if I wanted to use it for my own methods? For example, let's say that I perform an extremely expensive calculation and want all my 4 cores to work on it. I would have something like this:

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

But since I do not have the await keyword, the method is simply considered synchronous. I would like to call it 4 times outside so that it can work on all of my cores, while I show something reasonable to the user (for example, "Please wait ..."). The only solution I could figure out was to add await Task.Yield(); at the beginning of the method. Something like that:

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

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

+6
source share
1 answer

So, first you need a method that does a very expensive job 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 run multiple instances of this work in the 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 make a non-blocking wait until all of them are completed:

 await Task.WhenAll(tasks); 
+13
source

All Articles