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

C# 降低Task.Factory.StartNew线程的优先级,c#,.net,multithreading,.net-4.0,taskfactory,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 }); 当您决定是否使用线程池时,这是“不要做”之一;-) 详情如下: 因此答案是“不,您不能为在ADS池中创建的

下面的代码将启动一个新线程来执行此任务。有什么方法可以控制该线程的优先级吗

Task.Factory.StartNew(() => {
    // everything here will be executed in a new thread.
    // I want to set the priority of this thread to BelowNormal
});
当您决定是否使用线程池时,这是“不要做”之一;-)

详情如下:

因此答案是“不,您不能为在ADS池中创建的线程指定特定优先级”


对于常规线程,我敢打赌您已经知道属性

用于设置任务的优先级,请查看Microsoft expert在中描述的自定义任务调度程序。关于更多细节,请不要错过他在第一句中提到的前两篇文章的链接


对于您的问题,听起来您可能希望查看
队列taskscheduler

任务的线程优先级可以在执行任务的实际方法内设置。但是,一旦你完成了避免问题的工作,不要忘记恢复优先级

因此,首先开始任务:

newtaskFactory().StartNew(StartTaskMethod)

然后设置线程优先级:

void StartTaskMethod()
{
    try
    {
        // Change the thread priority to the one required.
        Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;

        // Execute the task logic.
        DoSomething();
    }
    finally
    {
        // Restore the thread default priority.
        Thread.CurrentThread.Priority = ThreadPriority.Normal;
    }
}

更改优先级时,请记住:

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

您可以使用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 = string.Format("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
    }
}
公共类优先级调度程序:任务调度程序
{
public static PriorityScheduler overnormal=新的PriorityScheduler(ThreadPriority.overnormal);
public static PriorityScheduler BelowNormal=新的PriorityScheduler(ThreadPriority.BelowNormal);
public static PriorityScheduler Lowest=新的PriorityScheduler(ThreadPriority.Lowest);
private BlockingCollection_tasks=新建BlockingCollection();
私有线程[]\u线程;
私有线程优先级_优先级;
私有只读int_maximumConcurrencyLevel=Math.Max(1,Environment.ProcessorCount);
公共优先级计划程序(线程优先级)
{
_优先级=优先级;
}
公共覆盖int最大并发级别
{
获取{return\u maximumConcurrencyLevel;}
}
受保护的重写IEnumerable GetScheduledTasks()
{
返回任务;
}
受保护的覆盖无效队列任务(任务任务)
{
_任务。添加(任务);
如果(_threads==null)
{
_线程=新线程[_最大并发级别];
对于(int i=0;i<\u threads.Length;i++)
{
int local=i;
_线程[i]=新线程(()=>
{
foreach(任务中的任务t_tasks.GetConsumingEnumerable())
基.TryExecuteTask(t);
});
_线程[i].Name=string.Format(“PriorityScheduler:”,i);
_线程[i]。优先级=\u优先级;
_线程[i]。IsBackground=true;
_线程[i].Start();
}
}
}
受保护的覆盖bool TryExecuteTaskInline(任务任务,bool任务先前排队)
{
return false;//我们可能不希望执行应作为高优先级或低优先级内联调度的任务
}
}
注:

  • 工作线程都是后台线程,因此不应使用此调度器调度重要任务;只有那些在进程关闭时可以丢弃的
  • 改编自
  • 我不完全理解每一个超控;只需使用Bnaya对
    MaximumConcurrencyLevel
    GetScheduledTasks
    TryExecuteTaskInline
    的选择即可

是的,我知道Thread.Priority。但我只是想知道,使用任务工厂而不是使用线程的对象是否可行。在第一个链接中,描述说,使用任务工厂是不可能的。无论如何,我永远不需要改变池中线程的优先级,也不能100%确定这是真的。我最初选择@Roman Starkov answer,但在负载测试之后,它失败了。我的答案是:如果你想改变优先级,就使用线程。不要使用任务管理器这种方法对我来说很危险。这不是在一个线程池线程上设置优先级吗?您不知道下一步将在哪里使用该线程。@Brannon,我想通过任务调度器更改优先级也会产生类似的效果。一般来说,您根本不会更改优先级,但如果您需要更改优先级,那么您的更改方式也没有什么不同。@net_prog,我想您不明白布兰农的意思。线程池中的线程被重新使用。下一次您想要重用线程时,必须确保适当的优先级。默认行为是使线程具有正常优先级。如果您使用使用线程池的第三方库,那么如果优先级不符合预期,您可能会遇到问题。(上面的注释现在大多已过时,因为代码已更新为使用try..finally。但是,可以进一步改进以捕获初始线程优先级,而不是将值设置回正常值。)由于一个线程可以执行不同的任务,是否有可能该线程被抢占以执行另一个任务,然后毫无理由具有更高的优先级?现在看来,它在GitHub上有一个(未认证)位置,许可证已更改(可能不合法),并且添加了一些用于处理最终确定/处置的内容,虽然AppDomain本身可能不会崩溃(IRegisteredObject)。如果您只是想利用TaskParallelLibrary的易用性并设置优先级,那该多详细啊。。。不过我无意冒犯。感谢您的回答。此解决方案似乎有效,但在重载情况下会死锁。@Quarkly所有并发都由
BlockingCollection
处理,这里没有奇特的多线程。你确定是这个密码导致了死锁吗