Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# PLINQ:如何在超过4个线程上运行并行查询?_C#_Plinq - Fatal编程技术网

C# PLINQ:如何在超过4个线程上运行并行查询?

C# PLINQ:如何在超过4个线程上运行并行查询?,c#,plinq,C#,Plinq,更新-更改问题的标题以反映我真正想要的 考虑以下代码: // this query generates 12 instances of Func<int>, which each when executed // print something to the console and wait for 1 second. var actions = Enumerable.Range(0, 12).Select(i => new Func<int>(() => {

更新-更改问题的标题以反映我真正想要的

考虑以下代码:

// this query generates 12 instances of Func<int>, which each when executed
// print something to the console and wait for 1 second.
var actions = Enumerable.Range(0, 12).Select(i => new Func<int>(() =>
{
    Console.WriteLine("{0} - waiting 1 sec", i);
    Thread.Sleep(1000);
    return 1;
}));

// define a parallel query. Note the WithDegreeOfParallelism call here.
var query = from action in actions.AsParallel().WithDegreeOfParallelism(12)
            select action();

// execute, measuring total duration
var stopw = Stopwatch.StartNew();
query.ToList();
Console.WriteLine(stopw.Elapsed);
Console.WriteLine(Environment.ProcessorCount); // 3 on my machine

尝试在并行循环中使用选项
TaskCreationOptions.LongRunning
启动新任务。它们将立即启动,而不是等待线程池中的线程可用。

正如我在degreeofparallelism中所说的,并行性只是设置了一个上限。尝试将任务从10增加到100。你最终会得到大约10个金币来支付所有100个金币。您的代码适用于具有较小操作的大量任务。 并添加
Console.WriteLine(“{0}个线程”,Process.GetCurrentProcess().threads.Count)在您的任务中,然后您可以看到创建了多少线程。(线程计数不是plinq创建的线程计数。请查看它是如何增加的)


有很多方法可以使用PLinq实现并行性。阅读这篇文章。您需要为相关需求选择最佳方式以获得更好的性能。

带degreeofparallelism指示PLINQ应创建多少任务,但不一定要使用多少线程

由于任务作为线程池上的工作项执行,因此执行查询的线程数将受到线程池大小的限制。ThreadPool将根据需要添加线程,但可能需要一段时间-ThreadPool可能每秒添加2个线程左右

如果要快速向线程池添加线程,可以使用SetMinThreads方法。如果将此代码放在代码开头,测试应在一秒钟左右完成:

int prevThreads, prevPorts;
ThreadPool.GetMinThreads(out prevThreads, out prevPorts);
ThreadPool.SetMinThreads(12, prevPorts);

您可以决定需要多少线程,然后使用SetMinThreads和SetMaxThreads设置线程池大小的界限。

WithDegreeOfParallelism仅设置上限。PLinq将选择低于该数字ROK的最佳并行度,但它如何知道4是这种情况下的最佳值?有没有办法用PLINQ在12个并发线程上强制运行此功能?实际上,最适合您的是3个线程。为什么您希望运行的线程数超过您的核心数?只有开销增加了。@Henk您能详细说明为什么不应该用Thread.Sleep来模拟吗?您应该在这里使用异步代码,而不是像这样捆绑(线程池)线程。P/LINQ不是全做全做的框架,它适合cpu密集型操作,但在这种情况下,您应该在web请求上使用BeginXYZ操作之类的东西。这样你就不会绑线了。
int prevThreads, prevPorts;
ThreadPool.GetMinThreads(out prevThreads, out prevPorts);
ThreadPool.SetMinThreads(12, prevPorts);