Threadpool +轮询C#.Net 3.5

问题描述 投票:3回答:2

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

我们在服务器上运行了一项服务,用于轮询我们客户端上的通知数据。我们希望该服务能够更快地处理数据。目前,我们现有的服务在单个线程上轮询和处理数据,这有时会导致每小时基于通知的延迟。我的计划是使用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中的maxthreads限制为3.我做对了吗?想就我的概念提出一些指导和优点和缺点。

c# multithreading windows-services threadpool
2个回答
2
投票

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

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描述的模式。


0
投票

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

在伪代码中 -

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的最后一行只是递减值。

你可以做各种各样的花哨的东西,比如在一个Action()中包装你的workerFunc,它自己递减计数器,防止你的workerFunc需要任何与myWorkLauncher类的连接。或者,您可以使用AutoResetEvent或类似替换简单的Thread.Sleep。

© www.soinside.com 2019 - 2024. All rights reserved.