为了账号安全,请及时绑定邮箱和手机立即绑定

线程池 + 轮询 C# .Net 3.5

线程池 + 轮询 C# .Net 3.5

C#
GCT1015 2022-01-15 17:18:30
我是多线程的新手,想请教您的建议和指导。我们在我们的服务器上运行了一项服务来轮询数据以获取我们客户的通知。我们希望该服务能够更快地处理数据。目前,我们现有的服务在单个线程上轮询和处理数据,这有时会导致每小时的通知延迟。我的计划是使用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();            }        }    }}在运行控制台应用程序时,我注意到线程数一直在增加,尽管我将 maxthreads 限制在ThreadPool3 以内。我做对了吗?想对我的概念提出一些指导和利弊。
查看完整描述

2 回答

?
MYYA

TA贡献1868条经验 获得超4个赞

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

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

由于以下原因,它无法处理更改:

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

参见:MSDN


所以,你可以做的是这样的;

ThreadPool.SetMaxThreads(16, 16);

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

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


查看完整回答
反对 回复 2022-01-15
?
动漫人物

TA贡献1815条经验 获得超10个赞

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


在伪代码中-


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);

}

工作函数的最后一行只是递减值。


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


查看完整回答
反对 回复 2022-01-15
  • 2 回答
  • 0 关注
  • 354 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号