Reputation: 1087
I am trying to get to grips with Tasks and the Async Await keywords. I have a little sample method which essentially invokes n number of methods. Two key points to note are
With this here is the code.
public async void Handle<T>(T entry) {
await Task.Run(() => {
Parallel.ForEach(_handlers, pair => {
pair.Value.Invoke(_reference, new object[] {
entry
});
});
});
My question is did I actually gain any async or parallelism out of the code above?
Upvotes: 2
Views: 126
Reputation: 456487
I'm assuming that you're running in a UI application, since parallel code on a server is quite rare.
In this case, wrapping parallel code in a Task.Run
is perfectly normal, and a common pattern when you wish to execute parallel code asynchronously.
I would make a few changes:
async void
. Return a Task
, so you can handle errors more cleanly.Async
).Task
directly instead of async
/await
(if your entire async
method is just to await
a task, you can avoid some overhead just by returning the task directly).Like this:
public Task HandleAsync<T>(T entry) {
return Task.Run(() => {
Parallel.ForEach(_handlers, pair => {
pair.Value.Invoke(_reference, new object[] {
entry
});
});
});
I'd also consider two other possibilities:
Parallel.Invoke
instead of Parallel.ForEach
. It seems to me that Parallel.Invoke
is a closer match to what you're actually trying to do.public void Handle<T>(T entry)
) and calling it with Task.Run
(e.g., await Task.Run(() => Handle(entry));
). If your Handle[Async]
method is intended to be part of a general-purpose library, then you want to avoid the use of Task.Run
within your asynchronous methods.Upvotes: 5
Reputation: 1500515
No, you've gained nothing here. Even if you made it return Task
(so that the caller could check when everything had finished) you'd be better off without async:
public Task Handle<T>(T entry)
{
return Task.Run(() =>
{
Parallel.ForEach(_handlers, pair =>
{
pair.Value.Invoke(_reference, new object[] { entry });
});
});
}
Upvotes: 1