I have a method which does 2 independent pieces of logic. I was hoping I can run them both at the same time .. and only continue afterwards when both those child methods have completed.
I was trying to get my head around the async/await
syntax but I just don't get it.
Here's the code:
public PewPew SomeMethod(Foo foo)
{
var cats = GetAllTheCats(foo);
var food = GetAllTheFood(foo);
return new PewPew
{
Cats = cats,
Food = food
};
}
private IList<Cat> GetAllTheCats(Foo foo)
{
// Do stuff, like hit the Db, spin around, dance, jump, etc...
// It all takes some time.
return cats;
}
private IList<Food> GetAllTheFood(Foo foo)
{
// Do more stuff, like hit the Db, nom nom noms...
// It all takes some time.
return food;
}
So with that code above, I want to say : go and get all the cats and food at the same time. Once we're finished, then return a new PewPew
.
I'm confused because I'm not sure which classes above are async
or return a Task
, etc. All of em? just the two private ones? I'm also guessing I need to leverage the Task.WaitAll(tasks)
method, but I'm unsure how to setup the tasks to run at the same time.
Suggestions, kind folks?
Here is what you may want to do:
There are two things you need to understand here:
1) What is diff between this:
And this:
Both will give you similar result in the sense let the 2
async
tasks finish and thenreturn new PewPew
- however, difference is thatTask.WaitAll()
will block the current thread (if that is UI thread, then UI will freeze). instead,await
will break down theSomeMethod
say in a state machine, and return from theSomeMethod
to its caller as it encountersawait
keyword. It will not block the thread. The Code belowawait
will be scheduled to run whenasync
task is over.2) You could also do this:
However, this will not start the
async
tasks simultaneously. Second task will start after the first is over. This is because how theawait
keyword works, hope that helps...EDIT: How to use
SomeMethod
- somewhere at the start of the call tree, you have to useWait()
orResult
property - OR - you have toawait
fromasync void
. Generally,async void
would be an event handler:If not then use
Result
property.By far the easiest way to do this is to use
Parallel.Invoke()
Parallel.Invoke()
will wait for all the methods to return before it itself returns.More information here: http://msdn.microsoft.com/en-us/library/dd460705.aspx
Note that
Parallel.Invoke()
handles scaling to the number of processors in your system, but that only really matters if you're starting more than just a couple of tasks.You can use the TPL to wait for multiple tasks while they are running. See here.
Like this:
Adding to the other answers, you could do something like:
You don't have to use async if you're not in an async method or you're using an older version of the .Net framework.. just use Tasks for simplicity: