繁体   English   中英

如何将这个长期运行的后台任务转换为异步/等待?

[英]How can I convert this long-running background task to 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
  • 根据需要通过方法签名添加异步/唤醒

使该代码在后台线程上运行并允许使用异步/等待模式的正确方法是什么?

简而言之,除非您特别需要,否则请勿使用Task.Factory.StartNewTaskCreationOptions.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/ 5月21日/的-危险-的-Task.Factory.StartNew.html

正在将应用程序更新为使用异步/等待

这并不意味着一切都应该变得异步。 是否是候选者取决于它如何与呼叫者和被呼叫者交互。 您没有发布任何内容。

您可以(应该)保持原样。

Otoh,总是有延迟的循环。 为什么不在计时器上运行它呢?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM