Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.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# 第三方物流推动更高的并行性_C#_.net_Multithreading_Task Parallel Library - Fatal编程技术网

C# 第三方物流推动更高的并行性

C# 第三方物流推动更高的并行性,c#,.net,multithreading,task-parallel-library,C#,.net,Multithreading,Task Parallel Library,将任务排队到线程池时,代码依赖默认的任务调度程序执行它们。在我的代码示例中,我可以看到7个Tasksmaximum在不同的线程上并行执行 new Thread(() => { while (true) { ThreadPool.GetAvailableThreads(out var wt, out var cpt); Console.WriteLine($"WT:{wt} CPT:{cpt}"); Thread.Sleep(5

任务
排队到线程池时,代码依赖默认的
任务调度程序
执行它们。在我的代码示例中,我可以看到7个
Tasks
maximum在不同的线程上并行执行

new Thread(() =>
{
    while (true)
    {
        ThreadPool.GetAvailableThreads(out var wt, out var cpt);
        Console.WriteLine($"WT:{wt} CPT:{cpt}");
        Thread.Sleep(500);
    }
}).Start();

var stopwatch = new Stopwatch();
stopwatch.Start();
var tasks = Enumerable.Range(0, 100).Select(async i => { await Task.Yield(); Thread.Sleep(10000); }).ToArray();
Task.WaitAll(tasks);
Console.WriteLine(stopwatch.Elapsed.TotalSeconds);
Console.ReadKey();
有没有办法强制调度程序在其他线程上启动更多的
任务
?或者框架中是否有一个更“慷慨”的调度器,而不实现自定义的调度器

编辑:

添加
ThreadPool.SetMinThreads(100,X)
似乎可以做到这一点,我认为等待释放线程,使线程池认为它可以启动另一个线程,然后立即恢复

默认情况下,最小线程数设置为系统上的处理器数。您可以使用SetMinThreads方法增加最小读取数。但是,不必要地增加这些值可能会导致性能问题。如果同时启动的任务太多,则所有任务都可能看起来很慢。在大多数情况下,线程池使用其自己的线程分配算法将执行得更好。将最小值减少到少于处理器数量也会影响性能

从这里开始:

我删除了AsParallel,因为它不相关,而且似乎让读者感到困惑。

试试这个:

您可以设置工作线程的数量(第一个参数)。

使用扩展名:

Enumerable.Range(0, 100).AsParallel().WithDegreeOfParallelism(x).Select(...
有没有办法强制调度程序在其他线程上启动更多任务

执行线程的数量不能超过CPU核心的数量。计算机就是这样工作的。如果您使用更多的线程,那么您的工作实际上会完成得更慢,因为为了运行,线程必须在内核中交换

或者框架中是否有一个更“慷慨”的调度器,而不实现自定义的调度器

PLINQ已经进行了调整,以最大限度地利用硬件


如果将
线程.Sleep
调用替换为实际使用CPU的调用(例如,
while(true);
),然后在任务管理器中查看CPU使用情况,您可以自己看到这一点。我的期望是,本例中PLINQ使用的7或8个线程是您的计算机所能处理的所有线程。

解释它可以通过
线程池完成的有用链接。SetMinThread


我假设您有8个以上的内核/cpu-s,对吗?@rudolf_franek 16个逻辑内核。我认为它应该能够在硬件级别交错更多线程,不是吗?这段代码想做什么?它混合了原始线程和任务,PLINQ*和一个小范围,以及处理线程的阻塞。任何假定的阻塞问题都是由代码本身引起的,而不是PLINQ、任务或线程的任何限制pool@user4388177
它应该能够在硬件级别交错更多线程
否,这称为抖动,是浪费。为什么在同一时间运行的线程数要多于内核数?无论如何你不能,你必须从一个线程切换到另一个线程。PLINQ使用的任务数量大致相当于用于划分和处理大量数据的核心数量。但是,您的代码没有数据,并且阻止了辅助任务。通过使用
Thread.Sleep
inside Select阻塞,您已经阻塞了PLINQ@user4388177如果您想实际测试PLINQ,请创建一个简单的测试,例如使用
Enumerable.Range(01000000).aspallel().Select(int i=>Math.Pow(i)).ToList()生成1M行并计算它们的平方。这将把1M行划分为大约与内核数量相同的分区,并全速处理每个分区,这一点都没有帮助。OP的代码在PLINQ查询中生成sleep语句。什么也不做,快一点也不做。在一个真实的示例中,较高的DOP会影响性能,因为PLINQ会尝试使用比内核更多的线程来处理(大)输入数据,从而导致线程切换完全不一致。它完全依赖于并行执行的代码。对于纯数学而言,you语句是有意义的,如果有任何等待涉及到的外部资源,它就没有意义(异步有时会出现这种情况,但情况不同)。@arbiter调用异步lambda的并行性不会有任何区别,只要它们点击
wait
方法返回。实际上,直到
await
它都是同步执行的,所以要么按照您的建议执行,要么添加
await
。完全不同意您的意见。第三方物流涵盖多种范式。PLINQ的创建是为了简化数据并行性,而不是数学。在这种情况下,使用比可以运行的线程更多的线程是没有意义的。它不适用于IO并行、异步编程,也不适用于只执行少量CPU密集型操作operations@arbiter这就是为什么PLINQ和Parallel.For/Foreach在将数据传递给辅助任务之前对数据进行分区,以避免在线程切换中浪费CPU时间。如果有很多IO,分区就没有什么意义。@user4388177问题是,您的代码除了使用至少3种不同的并发范例(PLINQ的数据并行性、异步/等待的任务并行性、原始线程)创建块之外,什么都不做。您遇到的任何问题都是由代码引起的itself@PanagiotisKanavosPLINQ是不相关的,原始线程仅用于监视。@user4388177否,它非常相关。正是它指定了工人的使用、分区和工人数量。您可以从代码中删除所有其他内容,它仍然可以正常工作。@PanagiotisKanavos remove
AsParallel
,您会得到相同的问题(现在我添加了
wait Task.Yield
)。@user4388177不,您不会得到相同的问题。你仍然有一个相当荒谬的问题,在它试图做的事情中有很多主要的问题,但实际上仍然没有任何它试图解决的合理问题。您正在试图找出如何编写无法完成任何任务的代码