如何使一定数量的线程一直运行

Mon*_*RPG 7 c# wpf multithreading multitasking threadpool

好的,我的问题.我想在一定数量之前启动线程.让我们说100.因此它将开始启动线程并连续检查正在运行的线程数.当达到最大数量时,它将停止启动新线程.但是通过适当的检查间隔或完成的线程将发出信号并且它将启动新线程.

通过这种方式,我将始终拥有一定数量的运行线程.

我通过使用睡眠和永久性来管理这个.所以我一直用给定的间隔检查总运行线程数,如果线程完成,请将其丢弃并重新开始.

但我的解决方案并不是让我成为一种正确的方式.我想如果完成的线程发出信号然后检查器会在最大线程数阈值以下时启动新的线程会更好.

我看到了很多线程池示例,但大多数都不包含任何排队的池,并且运行线程数量最多.我的意思是,他们只是继续启动线程,直到完成.但是让我说我​​有500k的网址可以收获.我不能在带有线程池的for循环中启动所有这些.

平台是c#4.5 WPF应用程序

以下是我的解决方案.其实我正在寻找一个更好的.没有改善这个.

private void Button_Click_4(object sender, RoutedEventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        startCrawler();
    });
}

void startCrawler()
{
    int irMaximumThreadcount = 100;
    List<Task> lstStartedThreads = new List<Task>();
    while (true)
    {
        for (int i = 0; i < lstStartedThreads.Count; i++)
        {
            if (lstStartedThreads[i].IsCompleted == true)
            {
                lstStartedThreads[i].Dispose();
                lstStartedThreads.RemoveAt(i);
            }
        }

        if (lstStartedThreads.Count < irMaximumThreadcount)
        {
            var vrTask = Task.Factory.StartNew(() =>
            {
                func_myTask();
            });
            lstStartedThreads.Add(vrTask);
        }

        System.Threading.Thread.Sleep(50);
    }
}

void func_myTask()
{

}
Run Code Online (Sandbox Code Playgroud)

Fel*_*lix 6

就个人而言,我会使用PLINQ,特别是WithDegreeOfParallelism方法,它将并发执行的数量限制为传入的值.

private IEnumerable<Action> InfiniteFunctions()
{
    while(true)
    {
        yield return func_myTask;
    }
}

private void Button_Click_4(object sender, RoutedEventArgs e)
{
    int irMaximumThreadcount = 100;
    InfiniteFunctions()
        .AsParallel()
        .WithDegreeOfParallelism(irMaximumThreadcount)
        .ForAll(f => f());
}
Run Code Online (Sandbox Code Playgroud)

编辑:实际上阅读文档似乎irMaximumThreadCount最多只能是64,所以要小心.

编辑2:好的,有一个更好的外观,它似乎Parallel.ForEach需要一个ParallelOptions参数,其中包括一个MaxDegreeOfParallelism不受限制的属性 - 检查出来.所以你的代码可能是这样的:

private void CrawlWebsite(string url)
{
    //Implementation here
}

private void Button_Click_4(object sender, RoutedEventArgs e)
{
    var options = new ParallelOptions() 
    { 
        MaxDegreeOfParallelism = 2000 
    };

    Parallel.ForEach(massiveListOfUrls, options, CrawlWebsite);
}
Run Code Online (Sandbox Code Playgroud)