Reputation: 1372
I have code that is kicking off work on a long-running background task with a heartbeat. The application is being updated to use async/await and I am having problems updating this code to follow suite. Here is the code, roughly:
private void StartBackgroundTasks(CancellationTokenSource cancelTokenSrc)
{
void TaskAction()
{
DoWork();
}
void HeartbeatAction()
{
var task = TaskFactory.CreateAndStartLongRunningTask(
TaskAction, cancelTokenSrc.Token);
while (true)
{
// checks Task.Status to figure out when to stop
if (!TryPerformHeartbeat(task)) break;
Task.Delay(TimeSpan.FromSeconds(20)).Wait();
}
}
TaskFactory.CreateAndStartLongRunningTask(HeartbeatAction);
}
And here is how the long-running tasks are being started:
internal static class TaskFactory
{
internal static Task CreateAndStartLongRunningTask(
Action action, CancellationToken? token = null)
{
return Task.Factory.StartNew(
action,
token ?? CancellationToken.None,
TaskCreationOptions.LongRunning,
TaskScheduler.Default);
}
}
From what I understand I need to:
Func<Task>
to CreateAndStartLongRunningTask
StartNew
to take async () => await taskFunc()
instead of action
What would be the correct way to get this code runs on a background thread and allows for the async/await pattern?
Upvotes: 0
Views: 2350
Reputation: 2228
Essentially in short unless you specifically need it you shouldn't use Task.Factory.StartNew
or TaskCreationOptions.LongRunning
. Just use Task.Run
like so:
var task = Task.Run(async () =>
{
while (true)
{
await TryPerformHeartbeat();
await Task.Delay(TimeSpan.FromSeconds(20));
}
}, token);
These two articles are helpful in explaining why: http://blog.i3arnon.com/2015/07/02/task-run-long-running/ and https://sergeyteplyakov.github.io/Blog/async/2019/05/21/The-Dangers-of-Task.Factory.StartNew.html
Upvotes: 4