c# - 降低 Task.Factory.StartNew 线程的优先级

标签 c# .net multithreading .net-4.0 taskfactory

像下面这样的代码将启动一个新线程来完成这项工作。有什么方法可以控制该线程的优先级吗?

Task.Factory.StartNew(() => {
    // everything here will be executed in a new thread.
    // I want to set the priority of this thread to BelowNormal
});

最佳答案

正如其他人所提到的,您需要指定一个自定义调度程序来完成您的任务。不幸的是,没有合适的内置调度程序。

您可以选择 Glenn 链接到的 ParallelExtensionsExtras,但如果您想要一些可以直接粘贴到您的代码中的简单内容,请尝试以下操作。像这样使用:

Task.Factory.StartNew(() => {
    // everything here will be executed in a thread whose priority is BelowNormal
}, null, TaskCreationOptions.None, PriorityScheduler.BelowNormal);

代码:

public class PriorityScheduler : TaskScheduler
{
    public static PriorityScheduler AboveNormal = new PriorityScheduler(ThreadPriority.AboveNormal);
    public static PriorityScheduler BelowNormal = new PriorityScheduler(ThreadPriority.BelowNormal);
    public static PriorityScheduler Lowest = new PriorityScheduler(ThreadPriority.Lowest);

    private BlockingCollection<Task> _tasks = new BlockingCollection<Task>();
    private Thread[] _threads;
    private ThreadPriority _priority;
    private readonly int _maximumConcurrencyLevel = Math.Max(1, Environment.ProcessorCount);

    public PriorityScheduler(ThreadPriority priority)
    {
        _priority = priority;
    }

    public override int MaximumConcurrencyLevel
    {
        get { return _maximumConcurrencyLevel; }
    }

    protected override IEnumerable<Task> GetScheduledTasks()
    {
        return _tasks;
    }

    protected override void QueueTask(Task task)
    {
        _tasks.Add(task);

        if (_threads == null)
        {
            _threads = new Thread[_maximumConcurrencyLevel];
            for (int i = 0; i < _threads.Length; i++)
            {
                int local = i;
                _threads[i] = new Thread(() =>
                {
                    foreach (Task t in _tasks.GetConsumingEnumerable())
                        base.TryExecuteTask(t);
                });
                _threads[i].Name = $"PriorityScheduler: {i}";
                _threads[i].Priority = _priority;
                _threads[i].IsBackground = true;
                _threads[i].Start();
            }
        }
    }

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        return false; // we might not want to execute task that should schedule as high or low priority inline
    }
}

注意事项:

  • 工作线程都是后台线程,所以重要的任务不应该使用这个调度器来调度;只有那些在进程关闭时可以丢弃的
  • 改编自an implementation by Bnaya Eshet
  • 我不完全理解每一个覆盖;只需使用 Bnaya 对 MaximumConcurrencyLevelGetScheduledTasksTryExecuteTaskInline 的选择。

关于c# - 降低 Task.Factory.StartNew 线程的优先级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3836584/

相关文章:

javascript - 如何从这个 json 字符串中读取数据?

c++ - 何时在 C++ 中使用多线程?

c# - 静态集合和asp.net

c# - 显示 Silverlight 的 ComboBox 组 header

c# - 使用搜索条件作为 "OR"语句识别具有白色 UI 自动化的 WPF 控件

c# - 事先检查 `System.Activator.CreateInstance(Of T)` 是否会失败

c# - 如何在整个 Windows 操作系统中更改光标(图像)

.net - UI线程的定义是什么? .NET 应用程序中是否只有一个 UI 线程?

c - 在 C 程序中轮询其他线程写入的变量是否安全?

c++ - Qt:我应该在线程上运行 QFileWatcher 吗?