Reputation: 10020
I'm trying to create Tasks that will run async methods, the issue is that I cannot await
the Action
parameter in the Task's constructor, or the the parameters for Task.Factory.StartNew
.
Depending on how I'm instantiating my tasks, I have different issues. I have provided seven examples with comments on the issues each creates below.
Example Code: (seven examples of task creation)
private ConcurrentDictionary<int, Task> Tasks { get; set; }
private bool active = true;
private async Task StartTasks()
{
int numTasks = 5;
for(int i = 0; i < numTasks; i++)
{
//Task status is almost instantly "RanTocompletion" while work is still being done
Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Cannot await method group
Task task = new Task(await DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Task status is almost instantly "RanTocompletion" while work is still being done
Task task = new Task(async (object state) => await DoWork(state), "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Throws a "Start may not be called on a promise-style task." Exception
Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap();
task.Start();
//Task starts doing work after Start() is called, then throws a "Start may not be called on a promise-style task." Exception
Task task = new Task(DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Task starts doing work, but status is "WaitingForActivation
Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning);
//Throws a "Start may not be called on a promise-style task." Exception
Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap();
//For checking up on tasks as work is done
Tasks.TryAdd(task.Id, Task);
}
}
private async Task DoWork(object state)
{
while (active)
{
await MakeHttpRequest();
await DoSomethingCpuBound();
//..etc
}
//do any cleanup and return
}
I cannot use Task.Run()
since that does not provide TaskCreationOptions
. These tasks will run for literal days.
How can I start a task to await an async action?
Upvotes: 0
Views: 3840
Reputation: 456322
How can I start a task to await an async action?
In the TAP, tasks are returned "hot". So you literally just need to call the method and keep the task it returns:
private ConcurrentDictionary<int, Task> Tasks { get; set; }
private async Task StartTasks()
{
for(int i = 0; i < 5; i++)
{
Task task = DoWork(null);
Tasks.TryAdd(task.Id, task);
}
}
I cannot use Task.Run() since that does not provide TaskCreationOptions. These tasks will run for literal days.
You don't need TaskCreationOptions
. The LongRunning
flag is just a hint, and the thread pool will recover within a couple of seconds even if you don't specify that hint. But that doesn't even matter, because your work is asynchronous so it doesn't need to run on the thread pool in the first place.
Upvotes: 2