Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax for launching many async tasks in c#

I'm having trouble using the new async/await tools in c#. Here is my scenario:

static async Task<bool> ManageSomeRemoteTask(int Id, bool flag)
{
    var result = await serviceClient.AuthenticateIdAsync(Id);
    [... Setup Some Data ...]
    await serviceClient.LongAndSlowRemoteCallAsync(Data);
}

static void SendATonOfJunkToSomeWebServiceThatDoesntSupportBatches
{
    var myTasks = Dictionary<int, Task<bool>>();
    while(IdsLeftToProcess > 0 )
    {
      Task<bool> t = ManageSomeRemoteTask(Id, true);
      myTasks.Add(IdsLeftToProcess ,t);
      myTasks[IdsLeftToProcess].Start();
      IdsLeftToProcess --;
    }

    Task.WaitAll(myTasks.Values.ToArray()); //Wait until they are all done
    [... Report statistics ...]
}

I have 1 problem in that when I try running this, I get an InvalidOperationException on the Start() with the error message "Start may not be called on a promise-style task." This error message doesn't seem to come up in Google or Bing so I'm not sure what it means. This is my number one concern, how to get this to run. I also tried TaskFactory.StartNew() but didn't understand how to pass parameters to my method that way.

like image 543
Jason Avatar asked Jun 27 '12 23:06

Jason


People also ask

How do I await multiple async?

In order to run multiple async/await calls in parallel, all we need to do is add the calls to an array, and then pass that array as an argument to Promise. all() . Promise. all() will wait for all the provided async calls to be resolved before it carries on(see Conclusion for caveat).

What is async await syntax?

The async function declaration declares an async function where the await keyword is permitted within the function body. The async and await keywords enable asynchronous, promise-based behavior to be written in a cleaner style, avoiding the need to explicitly configure promise chains.

Which method calls the async Task?

A synchronous method calls an async method, obtaining a Task . The synchronous method does a blocking wait on the Task .

Can you await a Task multiple times C#?

Calling await multiple times on a ValueTask / ValueTask<TResult> *. The wrapped object may have been reused by another operation. This differs from Task / Task<TResult> , on which you can await multiple times and always get the same result.


2 Answers

Tasks returned by async methods are always hot i.e. they are created in Running state. Try to remove task.Start() from you code - it should fix it.

A quote from Stephen Toub's Async/Await FAQ:

Do I need to “Start” Tasks created by methods marked as “async”?

No. Tasks returned from TAP methods are “hot”, meaning the tasks represent operations that are already in-progress. Not only do you not need to call “.Start()” on such tasks, but doing so will fail if you try. For more details, see FAQ on Task.Start.

like image 158
alexm Avatar answered Sep 21 '22 04:09

alexm


You don't need to start the Tasks returned by async method calls. They're started by default.

like image 40
spender Avatar answered Sep 21 '22 04:09

spender