首页 > 解决方案 > 如何在 .NET 中增加任务的优先级?

问题描述

我有一个程序可以生成具有随机内容的 txt 文件。必须生成许多文档,所以我使用任务来更快地完成工作。我想每隔几秒钟通知用户一次进度(例如:“从 100000 个文档中生成了 50000 个文档”)。我创建了另一个任务 RecordProgress(),它每 3 秒记录一次进度。

但是,如果程序生成许多任务,则 RecordProgress() 永远不会运行。如果程序只生成 4 个任务,则 RecordProgress() 运行正确,即。每 3 秒调用一次。但是,如果程序生成许多任务,则 RecordProgress() 仅在处理完成/接近完成时运行。

有什么办法可以提高 RecordProgress() 任务的优先级吗?

我已经尝试在每个任务中记录进度,但这会向控制台生成太多日志消息,这会严重减慢我的程序。

我尝试登录每个任务并在日志之间等待 3 秒,但是如果程序生成 50 个任务,那么 50 条消息将同时记录到控制台,这再次减慢了我的程序并且是不必要的。我宁愿每 3 秒向控制台发送一条日志消息。

public void RecordProgress() 
{
        Stopwatch sw = new Stopwatch();
        sw.Start();

        //only record data while this generator is generating
        while (_processing)
        {
            if(sw.ElapsedMilliseconds < _logFrequency)
                continue;

            Console.WriteLine("Generated " + _docsGenerated + " documents.");
            sw.Restart();
        }
}

public void GenerateDocs()
{
    List<Task> tasks = new List<Task>();

    _processing = true;
    for (i = 0; i < 50; i ++)
    {
        tasks.Add(Task.Run(() => DoWork());
    }

    //task which records progress
    //ONLY runs if not many tasks are created above
    Task.Run(() => RecordProgress());

    Task.WaitAll(tasks.ToArray());
}

无论该程序生成多少任务,我都希望 RecordProgress() 任务每 3 秒运行一次。

编辑:根据评论,我删除了 Thread.Sleep() 的使用。但是,这只会延迟我的 RecordProgress() 任务的开始。

我尝试在 RecordProgress() 中使用秒表来仅每 3 秒记录一次进度,但这会大大降低程序的性能。

所以新问题:如何在不使用严重影响性能的计时器的情况下记录任务进度?

标签: c#task-parallel-library

解决方案


在原始情况下,您创建了许多任务并耗尽了线程池中的可用线程。运行ReportProgresslast 会延迟其执行,直到大多数其他任务完成。我看到你更正了你的代码。

至于优先级问题。请记住,您无法更改任务的优先级。您可以通过实现自己的 TaskScheduler 来实现类似的效果,但默认情况下,所有任务都以正常优先级运行。

如果您确实需要以更高的优先级运行任务,则需要创建一个Thread并将其优先级设置为更高/最高。你应该非常小心的事情。


推荐阅读