Как я могу преобразовать эту длительную фоновую задачу в async / await? - PullRequest
0 голосов
/ 29 мая 2019

У меня есть код, который начинает работу над длительной фоновой задачей с биением.Приложение обновляется для использования async / await, и у меня возникают проблемы с обновлением этого кода в соответствии с комплектом.Вот код примерно:

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);
}

А вот как запускаются долгосрочные задачи:

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);
    }
}

Из того, что я понимаю, мне нужно:

  • передать Func<Task> на CreateAndStartLongRunningTask
  • изменить StartNew на async () => await taskFunc() вместо action
  • добавить асинхронное / ожидает через сигнатуры метода какНужен

Каким будет правильный способ заставить этот код работать в фоновом потоке и использовать шаблон асинхронного / ожидающего выполнения?

Ответы [ 2 ]

3 голосов
/ 29 мая 2019

Короче говоря, если вам это не нужно, вы не должны использовать Task.Factory.StartNew или TaskCreationOptions.LongRunning.Просто используйте Task.Run примерно так:

var task = Task.Run(async () =>
{
    while (true)
    {
        await TryPerformHeartbeat();
        await Task.Delay(TimeSpan.FromSeconds(20));

    }
}, token);

Эти две статьи помогут объяснить, почему: http://blog.i3arnon.com/2015/07/02/task-run-long-running/ и https://sergeyteplyakov.github.io/Blog/async/2019/05/21/The-Dangers-of-Task.Factory.StartNew.html

0 голосов
/ 29 мая 2019

Приложение обновляется для использования async / await

Это не значит, что все должно стать асинхронным. Если это кандидат, зависит от того, как он взаимодействует с звонящими и вызываемыми. Вы не опубликовали ничего из этого.

Вы можете (должны), вероятно, оставить все как есть.

Otoh, цикл с задержкой всегда подозрительный. Почему бы не запустить это на таймере?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...