gpt4 book ai didi

c# - 什么决定了 TaskFactory 产生的作业的线程数?

转载 作者:太空狗 更新时间:2023-10-29 17:35:45 27 4
gpt4 key购买 nike

我有以下代码:

var factory = new TaskFactory();
for (int i = 0; i < 100; i++)
{
var i1 = i;
factory.StartNew(() => foo(i1));
}

static void foo(int i)
{
Thread.Sleep(1000);
Console.WriteLine($"foo{i} - on thread {Thread.CurrentThread.ManagedThreadId}");
}

我可以看到它一次只执行 4 个线程(基于观察)。我的问题:

  1. 什么决定了一次使用的线程数?
  2. 我怎样才能取回这个号码?
  3. 如何更改此号码?

附言我的盒子有 4 个芯。

附言我需要有特定数量的任务(不能更多)由 TPL 并发处理,并以以下代码结束:

private static int count = 0;   // keep track of how many concurrent tasks are running

private static void SemaphoreImplementation()
{
var s = new Semaphore(20, 20); // allow 20 tasks at a time

for (int i = 0; i < 1000; i++)
{
var i1 = i;

Task.Factory.StartNew(() =>
{
try
{
s.WaitOne();
Interlocked.Increment(ref count);

foo(i1);
}
finally
{
s.Release();
Interlocked.Decrement(ref count);
}
}, TaskCreationOptions.LongRunning);
}
}

static void foo(int i)
{
Thread.Sleep(100);
Console.WriteLine($"foo{i:00} - on thread " +
$"{Thread.CurrentThread.ManagedThreadId:00}. Executing concurently: {count}");
}

最佳答案

当您在 .NET 中使用 Task 时,您是在告诉 TPL 安排一项工作(通过 TaskScheduler)在 上执行线程池。请注意,工作将尽早安排,但安排程序认为合适。这意味着 TaskScheduler 将决定使用多少个线程来运行 n 个任务以及在哪个线程上执行哪个任务。

TPL 调整得非常好,并会在执行您的任务时不断调整其算法。因此,在大多数情况下,它会尽量减少争用。这意味着如果您正在运行 100 个任务并且只有 4 个内核(您可以使用 Environment.ProcessorCount),那么在任何给定时间执行超过 4 个线程是没有意义的,因为否则它需要做更多的上下文切换。现在有时您想要显式覆盖此行为。假设您需要等待某种 IO 完成,这是一个完全不同的故事

总而言之,信任 TPL。但是,如果您坚持为每个任务生成一个线程(这并不总是一个好主意!),您可以使用:

Task.Factory.StartNew(
() => /* your piece of work */,
TaskCreationOptions.LongRunning);

这会告诉 DefaultTaskscheduler 为该工作显式生成一个新线程。

您也可以使用自己的 Scheduler 并将其传递给 TaskFactory。您可以找到一大堆 Scheduler HERE .

请注意,另一种选择是使用 PLINQ,它在默认情况下再次分析您的查询并决定并行化它是否会产生任何好处,同样在在您确定启动多个线程的地方阻塞 IO 会导致更好的执行您可以通过使用 WithExecutionMode(ParallelExecutionMode.ForceParallelism) 强制并行性然后您可以使用 WithDegreeOfParallelism ,提示要使用多少个线程但是请记住,不能保证您会得到那么多线程,如MSDN说:

Sets the degree of parallelism to use in a query. Degree of parallelism is the maximum number of concurrently executing tasks that will be used to process the query.

最后,我强烈推荐阅读 THIS关于线程TPL 的精彩系列文章。

关于c# - 什么决定了 TaskFactory 产生的作业的线程数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34912698/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com