简体   繁体   English

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

[英]How can I convert this long-running background task to async/await?

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: 据我了解,我需要:

  • pass a Func<Task> to CreateAndStartLongRunningTask Func<Task>传递给CreateAndStartLongRunningTask
  • change StartNew to take async () => await taskFunc() instead of action 更改StartNew以使用async () => await taskFunc()而不是action
  • add async/awaits up through the method signatures as needed 根据需要通过方法签名添加异步/唤醒

What would be the correct way to get this code runs on a background thread and allows for the async/await pattern? 使该代码在后台线程上运行并允许使用异步/等待模式的正确方法是什么?

Essentially in short unless you specifically need it you shouldn't use Task.Factory.StartNew or TaskCreationOptions.LongRunning . 简而言之,除非您特别需要,否则请勿使用Task.Factory.StartNewTaskCreationOptions.LongRunning Just use Task.Run like so: 就像这样使用Task.Run

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 这两篇文章有助于解释原因: http : //blog.i3arnon.com/2015/07/02/task-run-long-running/https://sergeyteplyakov.github.io/Blog/async/2019/ 5月21日/的-危险-的-Task.Factory.StartNew.html

The application is being updated to use async/await 正在将应用程序更新为使用异步/等待

That does not mean everything should become async. 这并不意味着一切都应该变得异步。 If it is a candidate depends on how it interacts with callers and callees. 是否是候选者取决于它如何与呼叫者和被呼叫者交互。 You did not post any of that. 您没有发布任何内容。

You can (should) probably leave it as-is. 您可以(应该)保持原样。

Otoh, a loop with a delay is always suspect. Otoh,总是有延迟的循环。 Why not run this on a Timer? 为什么不在计时器上运行它呢?

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

相关问题 长期运行的后台任务中的Internet访问 - Internet access in a long-running background task 在后台运行一个长时间运行的并行任务,同时允许小的异步任务更新前台 - Running a long-running parallel task in the background, while allowing small async tasks to update the foreground MVVM-无需异步等待即可长时间运行的操作 - MVVM - long-running operation without async-await 使用 async/await 并行处理多个长时间运行的任务 - Parallelizing multiple long-running tasks with async/await 异步/等待具有进度/取消的长时间运行的API方法 - Async/await for long-running API methods with progress/cancelation Rx如何并行化长时间运行的任务? - Rx How to parallelize long-running task? 如何在C#Winforms应用程序中取消长时间运行的异步任务的执行 - How to cancel execution of a long-running async task in a C# Winforms app 将长时间运行的任务与异步/等待模式结合起来的正确方法是什么? - What is correct way to combine long-running tasks with async / await pattern? MVC中的异步/等待-为什么长时间运行操作期间释放线程很重要 - Async/await in MVC - Why is releasing thread during long-running operation important Task.Run与直接异步调用,用于启动长时间运行的异步方法 - Task.Run vs. direct async call for starting long-running async methods
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM