C# 作为低优先级CPU操作执行并行for循环的最简单方法是什么?

C# 作为低优先级CPU操作执行并行for循环的最简单方法是什么?,c#,.net,multithreading,parallel-processing,C#,.net,Multithreading,Parallel Processing,背景 从历史上看,我不必编写太多与线程相关的代码。我熟悉该流程,可以使用System.Threading在需要时执行我需要执行的操作。然而,我的大部分经验都被困在了.NET2.0的世界里(啊!),我需要一些帮助,在最新版本的.Net中执行一项非常简单的任务 我需要编写一个简单的并行作业,但我更希望它作为一个低优先级的任务来执行,而不会使我的电脑陷入停滞状态 下面是一个简单的并行示例,演示了我试图完成的工作类型。在本例中,我取一个随机数,如果新值大于已发现的上一个最大随机数,则存储它 请理解,本示

背景
从历史上看,我不必编写太多与线程相关的代码。我熟悉该流程,可以使用
System.Threading
在需要时执行我需要执行的操作。然而,我的大部分经验都被困在了.NET2.0的世界里(啊!),我需要一些帮助,在最新版本的.Net中执行一项非常简单的任务

我需要编写一个简单的并行作业,但我更希望它作为一个低优先级的任务来执行,而不会使我的电脑陷入停滞状态

下面是一个简单的并行示例,演示了我试图完成的工作类型。在本例中,我取一个随机数,如果新值大于已发现的上一个最大随机数,则存储它

请理解,本示例的目的是严格说明我有一个我希望重复执行、比较和存储的计算。我理解变量锁定的必要性,我也知道这段代码并不完美。然而,这是一个非常简单的例子,说明了我需要完成的任务的性质。如果你运行这段代码,你的CPU就会停下来

int i = 0;
ThreadSafeRNG r = new ThreadSafeRNG();
ParallelOptions.MaxDegreeOfParallelism = 4; //Assume I have 8 cores.
Parallel.For(0, Int32.MaxValue, (j, loopState) => 
{
    int k = r.Next();
    if (k > i) k = i;
}
如何并行地完成这项工作,并将其作为低优先级CPU作业执行。与标准for循环相比,上述机制提供了巨大的性能改进。然而,代价是,即使设置了
MaxDegreeOfParallelism
选项,我也无法使用我的计算机


我能做什么?

使用
并行。对于
方法,您不能设置线程优先级,因为它们是
线程池
线程


最好的办法是将
ParallelOptions.MaxDegreeOfParallelism
设置为
ProcessorCount-1
,这样你就有了一个空闲的内核来做其他事情(比如处理GUI)。

因为并行。对于使用线程池的线程,你不能将线程的优先级设置为低。但是,您可以更改整个应用程序的优先级

Process currentProcess = Process.GetCurrentProcess();
ProcessPriorityClass oldPriority = currentProcess.PriorityClass;

try
{
    currentProcess.PriorityClass = ProcessPriorityClass.BelowNormal;

    int i = 0;
    ThreadSafeRNG r = new ThreadSafeRNG();
    ParallelOptions.MaxDegreeOfParallelism = 4; //Assume I have 8 cores.
    Parallel.For(0, Int32.MaxValue, (j, loopState) => 
    {
        int k = r.Next();
        if (k > i) k = i;
    }
}
finally
{
    //Bring the priority back up to the original level.
    currentProcess.PriorityClass = oldPriority;
}

如果您真的不想降低整个应用程序的优先级,请将此技巧与某种形式的IPC(如WCF)相结合,并在第二个进程中运行您缓慢的长时间运行的操作,您可以根据需要启动并终止该进程。

不是重复的,但相关问题,谢谢@ledbutter。我想这是我发现的第一篇指向使用
ParallelOptions
对象的帖子之一。但是,我发现我需要将值设置为非常低的值,以查看差异。即便如此,我的电脑速度明显较慢,但它确实变得可用了。这是一种非选项。顺便说一下,
Random
上的非静态方法不是Stephen Toub的线程安全方法。唉。。。谢谢你们的评论,但这篇文章不是关于.Net的随机类。我知道它不是线程安全的。我可以很容易地调用一个名为
DoSimpleThreadSafeWork()
的方法,这就足够解决这个问题了。