【问题标题】:It takes more than a few seconds for a task to start running [duplicate]任务开始运行需要几秒钟以上[重复]
【发布时间】:2019-04-21 14:34:33
【问题描述】:

我正在使用WPFC# 开发应用程序。 我有以下代码:

        var tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
        Task task = Task.Factory.StartNew(() =>
        {
            // Some action that returns a boolean - **CODE_A**
        }).ContinueWith((task2) =>
        {
                result= task2.Result;
                if (!result)
                {
                    //Another action **CODE_B**
                }
            });

        }, token);

通常CODE_A会立即开始运行,不到一秒后,CODE_B开始执行。

但是,有时使用Task.Factory.StartNew 创建的任务需要超过 5 秒才能开始(一旦开始,执行速度和往常一样快)。

我不明白为什么任务开始运行需要这么长时间?我可以以某种方式影响任务优先级,因此它会在所有情况下立即开始运行吗?我猜(这只是一个假设)任务是由任务调度程序安排的,以便稍后执行?有没有办法让我一直强制任务立即运行?

【问题讨论】:

  • 所以如果我运行这个例子,我应该看到你的问题?如果不是(我确定我不会),这意味着您缺少相关信息,这个控制台、应用程序、服务器应用程序是什么,是否有很多任务正在发生,等等
  • 如果你的代码中有一个非常具体的部分(不是全部)你想提示你不喜欢它延迟,然后考虑使用LongRunning。这有点滥用,但它可能会起作用。 docs.microsoft.com/en-us/dotnet/api/…

标签: c# asynchronous task taskfactory continuewith


【解决方案1】:

任务安排在线程池上(默认情况下)。如果有很多其他任务/线程池使用情况(特别是如果正在创建长时间运行的任务但没有这样标记),则线程池可能需要一段时间才能扩展,以便线程可用于执行新排队的项目。

所以,我会从整体上审视您的系统,看看您是否在线程池中投入了过多的工作或使用不当。

我能否以某种方式影响任务优先级,使其在所有情况下都立即开始运行?

好吧,您可以手动创建线程并接管所有使用,但请注意,即使在那里它也不是“立即的”。它与操作系统选择调度任何新创建的线程一样快。

或者,如果您确实需要“立即”运行代码,请在您已经知道已安排并正在运行的线程上运行它 - 您自己的当前线程。当然,这样您就失去了要求 TPL 处理任务并在任务完成时收到通知的优势。并且可能会占用一个宝贵的线程,例如 UI 线程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-05
    • 2014-10-18
    • 2018-09-24
    相关资源
    最近更新 更多