C#线程池限制线程

jas*_*den 36 c# multithreading threadpool c#-2.0

好吧......我给了网站一个公平的搜索,并阅读了很多关于这个主题的帖子.我发现了这个问题:C#中一个简单线程池的代码特别有用.

但是,总是看起来,我需要的东西略有不同.

我查看了MSDN示例,并根据我的需要进行了调整.我引用的示例如下:http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx

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

我读过的所有内容似乎都表明ThreadPool班级是主要候选人.这就是事情变得棘手的事情.我可能需要发出100次这样的事情,但我最多只能运行3个线程(对于这个特定的任务).

我已经尝试设置MaxThreadsThreadPool通过:

ThreadPool.SetMaxThreads(3, 3);
Run Code Online (Sandbox Code Playgroud)

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

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

所以我的问题的核心是,如何确保或指定可以为其代码运行的最大线程数,但让代码继续运行更多线程,因为之前的线程完成直到任意点?我是以正确的方式解决这个问题吗?

此致

贾森


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

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

[此处的文字是网站的复制/粘贴]

Semaphore容量为1的A 类似于a Mutexlock,除了Semaphore没有"所有者" - 它与线程无关.任何线程都可以调用Releasea Semaphore,而使用Mutexlock,只有获得资源的线程才能释放它.

在下面的示例中,十个线程执行一个循环,Sleep中间有一个语句.A 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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mic*_*ren 30

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


您无法管理线程池的大小(或者实际上关于它的任何内容).

在这种情况下,我将使用信号量来管理对资源的访问.在您的情况下,您的资源正在运行Web scrape,或计算某些报告等.

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

System.Threading.Semaphore S = new System.Threading.Semaphore(3, 3);
Run Code Online (Sandbox Code Playgroud)

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

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();
}
Run Code Online (Sandbox Code Playgroud)

每个线程将在S.WaitOne()上阻塞,直到给出信号继续.一旦S减少了3次,所有线程都会阻塞,直到其中一个增加计数器.

这个解决方案并不完美.


如果您想要更清洁,更高效的东西,我建议您使用BlockingQueue方法,其中您将要执行的工作排入全局阻塞队列对象.

同时,你有三个线程(你创建的 - 不在线程池中),弹出队列中的工作来执行.这不是那么棘手的设置,而且非常快速和简单.

例子: