【问题标题】:Threadpool + Polling C# .Net 3.5线程池 + 轮询 C# .Net 3.5
【发布时间】:2019-02-17 20:33:36
【问题描述】:

您好,我是多线程新手,想请教您的建议和指导。

我们的服务器上运行了一项服务,用于轮询数据以获取客户端的通知。我们希望该服务能够更快地处理数据。目前,我们现有的服务在单个线程上轮询和处理数据,这有时会导致每小时的通知延迟。我的计划是使用ThreadPool 来同时处理数据。我有这段代码可以模拟我的计划和想法。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Security;
using System.Text;
using System.Threading;
using System.Xml;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Web; 

namespace ThreadPooling
{
    class Program
    {
        static int nMaxRecord = 0;
        static ManualResetEvent mre = new ManualResetEvent(false);
        static Timer TestThread = null;
        static void Main(string[] args)
        {
            TestThread = new Timer(new TimerCallback(ProcessWithThreadPoolMethod), null, 500, Timeout.Infinite);
            Thread.Sleep(Timeout.Infinite);
        }

        static void ProcessWithThreadPoolMethod(object ostate) // Sample processing of data
        {
            nMaxRecord = 1300;
            ThreadPool.SetMaxThreads(3, 0);
            for (int i = 0; i < 1300; i++)
            {
                ThreadPool.QueueUserWorkItem(ProcessWithThreadMethod, i);
            }

            mre.WaitOne();
            Console.WriteLine("Test");

            TestThread.Change(5000, Timeout.Infinite);
        }

        static void ProcessWithThreadMethod(object callback)
        {
            for (int i = 0; i <= 10; i++)
            {
                Console.WriteLine((int)callback);
            }

            if(Interlocked.Decrement(ref nMaxRecord) == 0)
            {
                mre.Set();
            }
        }
    }
}

在运行控制台应用程序时,我注意到线程数一直在增加,尽管我将 ThreadPool 中的最大线程数限制为 3。我做对了吗?想问一些关于我的概念的指导和优缺点。

【问题讨论】:

  • 也许阅读“备注”部分并检查其中的要点:docs.microsoft.com/en-us/dotnet/api/…,还要检查 SetMaxThreads 的返回值。是false吗?
  • @MrinalKamboj;这在 .net 3.5 中可用吗?
  • @MrinalKamboj "从 .NET Framework 4 开始,TPL 是首选方式" Source OP 在 3.5
  • @Stefan 错过了那部分,是的,它从 .Net 4.0 开始
  • @JonathanDaniel:是的,ThreadPool 只是调节产生的线程数量。信号量就像一个保镖:它调节并发活动线程。注意:它通过等待来做到这一点,所以如果你触发 1300 个线程,并允许 3 个同时处于活动状态; 1297 将等待。

标签: c# multithreading windows-services threadpool


【解决方案1】:

你应该测试以下的返回值:

ThreadPool.SetMaxThreads(3, 0); //returns false on normal machines.

因此无法处理更改:

您不能将工作线程或 I/O 完成线程的最大数量设置为小于计算机上处​​理器数量的数字。要确定存在多少处理器,请检索 Environment.ProcessorCount 属性的值。此外,您不能将工作线程或 I/O 完成线程的最大数量设置为小于相应的工作线程或 I/O 完成线程的最小数量。要确定最小线程池大小,请调用 GetMinThreads 方法。

见:MSDN


那么,你能做的就是这样的事情;

ThreadPool.SetMaxThreads(16, 16);

但我假设您试图降低ThreadPool 的速度。一般来说,这不是一个好主意。对于这种逻辑,您需要一个替代方案。

信号量可能是一个选项,如here 所述,或@Fildor 描述的模式。

【讨论】:

  • 谢谢!!!,可惜我无法阅读 SetMaxThread 文档。所以我们不能将最大线程数限制为低于处理器数。我们想避免 CPU 峰值,所以我将它设置为 3。当我在我们的暂存服务器上测试服务时,我还注意到它创建了 1K + 线程,尽管 CPU 使用率约为 40% - 50% 是正常的吗?
  • 然后使用Producer-Consumer-Pattern。不要每个项目使用一个线程,而是将项目保留在队列中并仅使用您认为合适的线程数来使用它们。 @JonathanDaniel
  • `我还注意到它创建了 1K + 线程,尽管 CPU 使用率约为 40% - 50% 是正常的`这取决于它在做什么。 1k+线程很多。 CPU使用率也很高。但是,如果您的系统正在处理很多事情,那么这是有道理的。如果您不期望这些负载:有问题。
  • @Fildor 感谢您的建议。您是否有任何关于如何开始使用生产者-消费者模式的文章或示例?如果你不介意的话。
  • 刚刚发现这个:stackoverflow.com/a/47179576/982149。也许它可以让你“受到启发”。
【解决方案2】:

你不能限制线程池,但为什么不在启动一个新线程之前检查一个简单的增量/减量计数器呢?

在伪代码中-

volatile int currentThreadCount = 0;

void myWorkLauncher()
{
   while(<I have work to do>)
   {
      if(currentThreadCount < threshold)
      {
          currentThreadCount ++;
          ThreadPool.QueueUserWorkItem(workerFunc);
      }
      else
      {
          Thread.Sleep(500);
      }
   }
   Thread.Sleep(500);
}

workingFunc 的最后一行只是递减值。

你可以做各种花哨的事情,比如将你的 workerFunc 包装在一个 Action() 中,它本身会递减计数器,防止你的 workerFunc 需要与 myWorkLauncher 类的任何连接。或者,您可以将简单的 Thread.Sleep 替换为 AutoResetEvent 或类似的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-17
    • 2020-04-24
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 2011-02-27
    相关资源
    最近更新 更多