【问题标题】:How to restart System.Threading.Tasks.Task in C# [duplicate]如何在 C# 中重新启动 System.Threading.Tasks.Task [重复]
【发布时间】:2014-10-02 13:23:38
【问题描述】:

我正在开发一个应用程序,其中我有一个可以在以后停止和重新启动的任务。 为此我有两种方法:

public static void TaskProcess()
    {
        var tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
        var task = new Task(
            () =>
                {
                    DoWork(token);
                }, 
            token);

        task.ContinueWith(
            task1 =>
                {
                    Console.WriteLine("Task finished... press any key to continue");
                    Console.ReadKey();
                    Console.WriteLine("Press q to quit...");
                },
            token);

        task.Start();

        string input;
        while ((input = Console.ReadLine()) != "q")
        {
            if (input == "c")
            {
                tokenSource.Cancel();
            }
            if (input == "r")
            {
                if (task.IsCompleted)
                {
                    // Here i want to restart my completed task
                }
                else
                {
                    Console.WriteLine("Task is not completed");
                }
            }
        }
    }

    private static void DoWork(CancellationToken token)
    {
        int i = 0;
        while (true)
        {
            i++;
            Console.WriteLine("{0} Task continue...", i);
            Thread.Sleep(1000);

            if (token.IsCancellationRequested)
            {
                Console.WriteLine("Canceling");
                token.ThrowIfCancellationRequested();
            }
        }
    }

目前,我创建了新的 Task 和 CancellationToken 实例来“重新启动”任务,但如果可能的话,我正在寻找更好的东西:

if (input == "r")
            {
                if (task.IsCompleted)
                {
                    Console.WriteLine("Task is completed... Restarting");
                    tokenSource = new CancellationTokenSource();
                    token = tokenSource.Token;
                    CancellationToken token1 = token;
                    task = new Task(
                        () => DoWork(token1),
                        token);
                    task.Start();
                }
                else
                {
                    Console.WriteLine("Task is not completed");
                }
            }

感谢您的帮助。

【问题讨论】:

    标签: c# .net multithreading task


    【解决方案1】:

    不,TaskTaskCancellationSource 是使用和抛出对象。你不能重复使用它们。您必须像当前一样创建新对象。

    有道理,假设您取消了Task,稍后某些代码需要检查Task 的状态。在您重新启动任务后不久就出现了(不可能,说是为了解释),告诉状态是Running 已经是Canceled 任务会不会误导?

    【讨论】:

    • 每次重启都重新创建新实例,内存不够用?
    • @cYounes 是什么让你这么想?
    • 因为此代码将在服务中永久运行,并希望确保它不会产生任何错误:)
    • @cYounes 别担心,除非您存储对所有已创建对象的引用,否则垃圾收集器将收集它们。
    【解决方案2】:

    如果您尝试重新启动 System.Threading.Tasks.Task<TResult>,我认为您不能:正如 Task Cancellation guide 所说,当调用取消时,任务必须终止,并且由于任务已终止您无法重新启动它;所以你的做法是正确的。

    或者您是在问是否有更好的模式来处理这种工作流程?

    【讨论】:

    • Exaclty,我正在做的工作正常,但是如果我每次重新启动进程时都创建新实例,我会担心内存
    • 你为什么要担心使用的内存?任务在启动时从默认线程池(具有固定数量的可用线程)中分配,并在终止时释放,因此除非您泄漏对象或挂起任务,否则不会出现内存问题。您可以拥有的是开始一项新任务的开销,但只有您可以评估。
    猜你喜欢
    • 2011-07-20
    • 2021-08-27
    • 2021-01-09
    • 1970-01-01
    • 2012-06-16
    • 1970-01-01
    • 2019-01-25
    • 1970-01-01
    • 2023-03-12
    相关资源
    最近更新 更多