线程池 + 轮询 C# .Net 3.5

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


我们在我们的服务器上运行了一项服务来轮询数据以获取我们客户的通知。我们希望该服务能够更快地处理数据。目前,我们现有的服务在单个线程上轮询和处理数据,这有时会导致每小时的通知延迟。我的计划是使用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 以内。我做对了吗?想对我的概念提出一些指导和利弊。


GCT1015
浏览 370回答 2
2回答

MYYA

您应该测试以下的返回值:ThreadPool.SetMaxThreads(3,&nbsp;0);&nbsp;//returns&nbsp;false&nbsp;on&nbsp;normal&nbsp;machines.由于以下原因,它无法处理更改:您不能将工作线程或 I/O 完成线程的最大数量设置为小于计算机上处理器数量的数字。要确定存在多少处理器,请检索 Environment.ProcessorCount 属性的值。此外,您不能将工作线程或 I/O 完成线程的最大数量设置为小于相应的工作线程或 I/O 完成线程的最小数量。要确定最小线程池大小,请调用 GetMinThreads 方法。参见:MSDN所以,你可以做的是这样的;ThreadPool.SetMaxThreads(16,&nbsp;16);但我假设你试图降低ThreadPool.&nbsp;一般来说,这不是一个好主意。对于这种逻辑,您将需要一个替代方案。信号量可能是一个选项,如此处所述,或者@Fildor 描述的模式。

动漫人物

您不能限制线程池,但为什么不在启动新线程之前检查一个简单的增量/减量计数器呢?在伪代码中-volatile int currentThreadCount = 0;void myWorkLauncher(){&nbsp; &nbsp;while(<I have work to do>)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; if(currentThreadCount < threshold)&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentThreadCount ++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ThreadPool.QueueUserWorkItem(workerFunc);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.Sleep(500);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp;}&nbsp; &nbsp;Thread.Sleep(500);}工作函数的最后一行只是递减值。你可以做各种花哨的事情,比如将你的 workerFunc 包装在一个 Action() 中,它本身会减少计数器,防止你的 workerFunc 需要与 myWorkLauncher 类的任何连接。或者,您可以将简单的 Thread.Sleep 替换为 AutoResetEvent 或类似的。
打开App,查看更多内容
随时随地看视频慕课网APP