gpt4 book ai didi

C#线程池限制线程

转载 作者:IT王子 更新时间:2023-10-29 04:02:44 26 4
gpt4 key购买 nike

好吧...我对该网站进行了公平的搜索,并阅读了很多关于该主题的帖子。我发现了这个问题:Code for a simple thread pool in C#特别有帮助。

然而,一如既往,我需要的东西略有不同。

我查看了 MSDN 示例并根据我的需要对其进行了一些调整。我引用的例子在这里:http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx

我的问题是这样的。我有一组相当简单的代码,它通过 HttpWebRequestWebResponse 类加载网页,并通过 Stream 读取结果。我在一个线程中触发这个方法,因为它需要执行很多次。该方法本身很短,但它需要被触发的次数(每次都有不同的数据)会有所不同。它可以是 1 到 200 之间的任何值。

我读过的所有内容似乎都表明 ThreadPool 类是主要候选者。这就是事情变得棘手的地方。我可能需要触发这个东西说 100 次,但我最多只能运行 3 个线程(对于这个特定任务)。

我尝试通过以下方式在 ThreadPool 上设置 MaxThreads:

ThreadPool.SetMaxThreads(3, 3);

我不完全相信这种方法有效。此外,我不想破坏将在其上运行的系统上运行的其他网站或程序。因此,通过限制 ThreadPool 上的线程数量,我能否确定这仅适用于我的代码和我的线程?

MSDN 示例使用事件驱动方法并调用 WaitHandle.WaitAll(doneEvents); 我就是这样做的。

所以我的问题的核心是,如何确保或指定可以为他们的代码运行的最大线程数,但让代码继续运行更多的线程,因为前面的线程结束直到某个任意点?我的处理方式是否正确?

此致

杰森


好的,我添加了信号量方法并完全删除了 ThreadPool 代码。看起来很简单。我的信息来自:http://www.albahari.com/threading/part2.aspx

正是这个例子向我展示了如何:

[下面的文字是从网站上复制/粘贴的]

容量为 1 的 Semaphore 类似于 Mutexlock,除了 Semaphore没有“所有者”——它与线程无关。任何线程都可以在 Semaphore 上调用 Release,而使用 Mutexlock 时,只有获得资源的线程可以释放它。

在下面的示例中,十个线程执行一个循环,中间有一个 Sleep 语句。 Semaphore 确保不超过三个线程可以同时执行该 Sleep 语句:

class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // Available=3; Capacity=3

static void Main()
{
for (int i = 0; i < 10; i++)
new Thread(Go).Start();
}

static void Go()
{
while (true)
{
s.WaitOne();

Thread.Sleep(100); // Only 3 threads can get here at once

s.Release();
}
}
}

最佳答案

注意:如果您将此限制为“3”只是为了不让运行您的应用程序的机器不堪重负,我会首先确保这是一个问题。线程池应该为你管理这个。另一方面,如果您不想淹没其他资源,请继续阅读!


您无法管理线程池的大小(或者关于线程池的大部分内容)。

在这种情况下,我会使用信号量来管理对您的资源的访问。在您的情况下,您的资源正在运行网络抓取,或计算一些报告等。

为此,在您的静态类中创建一个信号量对象:

System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);

然后,在每个线程中,您执行以下操作:

System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);

try
{
// wait your turn (decrement)
S.WaitOne();
// do your thing
}

finally {
// release so others can go (increment)
S.Release();
}

每个线程都将阻塞在 S.WaitOne() 上,直到它收到继续执行的信号。一旦 S 递减 3 次,所有线程都将阻塞,直到其中一个线程递增计数器。

这个解决方案并不完美。


如果您想要更简洁、更高效的东西,我建议您使用 BlockingQueue 方法,在这种方法中,您可以将要执行的工作排入一个全局阻塞队列对象中。

与此同时,您有三个线程(您创建的——不在线程池中),从队列中弹出工作以执行。这并不难设置,而且非常快速和简单。

例子:

关于C#线程池限制线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/444627/

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