2

I have a method which is run n times with different parameters, simplified:

foreach(var param in params)
    ValueList.Add(SomeMethod(param));

I would like to do this:

foreach(var param in params)
    TaskList.Add(SomeMethodAsync(param));

foreach(var task in TaskList)
    ValueList.Add(await task);

async Task<SomeValue> SomeMethodAsync(SomeParam p)
{
     //What to do here
     //To make this call async
     return SomeMethod(p);
}

How do I have to modify the current Method to apply the async functionality? The SomeMethod does not use any framework-functions that provide async; it is fully synchronous.

To describe it in different words: I want n tasks of this method to run asynchronously/simultaneously using the new async/await keywords.

3
  • You may want to read Should I expose asynchronous wrappers for synchronous methods. Also, your second foreach loop can be replaced with var valueList = await Task.WhenAll(taskList);. Commented Nov 13, 2012 at 13:18
  • As I wrote in a comment below; In my case, I am communicating with 14 different servers at once (not webrequest or other async-able operations), there are no resources being used on the client end; I simply need to wait for all operations to finish. However, it seems to take equally long for the sum of operations, no matter if I do Parrallel.ForEach, Jobs.AsParallel.Select(x => SomeMethod(x)) or when I use Tasks. (actually Tasks took a little bit longer than the rest) The sum of time is well above the individual operation timeout time. Commented Nov 13, 2012 at 13:27
  • It seems the underlying framework blocks the queries internally, I have no other explanation for the behaviour. Commented Nov 14, 2012 at 18:48

2 Answers 2

2

If your method does not return an asynchronous result then there's no point using async/await.

If you just want to run your methods in parallel, use Parallel.ForEach

Parallel.ForEach(params, param => ValueList.Add(SomeMethod(param)));

If SomeMethod does not use a task, or await any framework async calls then it will run on a single thread, regardless of whether you add async to the method definition.

Your best option in that case is to run SomeMethod in a task.

async Task<SomeValue> SomeMethodAsync(SomeParam p)
{
    return await Task.Run<SomeValue>(() => SomeMethod(p));
}

Personally I think the Parallel.ForEach is clearer.

Sign up to request clarification or add additional context in comments.

6 Comments

True, but you should be aware that this introduces a new thread. Async doesn't necesseraly introduce new thread. You can use any kind of Task<T> for awaiting.
@BoasEnkler True, although the default task scheduler uses the thread pool instead of always spinning up a new task. But if the point is to run them in series and they block, async ain't gonna help.
Yes also true :-) But I thought more about concurrency and data race issues in general. So the code should be thread safe. And some behavior may change. Depending on the scenario
Yes I was a bit worried about what type ValueList is, and if it's not a threadsafe list there might be issues.
Maybe I explained it wrong; I want to know what I have to change in said method to make it work with async/await. Clarified the question.
|
1

Just make it a function returning task.

Task<SomeValue> SomeMethodAsync(SomePAram p)
{
    return Task<SomeValue>.Run(()=> SomeMethod());
}

SomeMethodAsync is awaitable now.

2 Comments

you need to add the await keyword after the return otherwise the compiler complains that the return value must be of type SomeValue instead of Task<SomeValue>.
@CameronMacFarland No , See the method declaration there is no async

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.