Threadpool + опрос C # .Net 3.5 - PullRequest
       15

Threadpool + опрос C # .Net 3.5

0 голосов
/ 13 сентября 2018

Привет, я новичок в многопоточности и хотел бы попросить вашего совета и рекомендаций.

На нашем сервере запущена служба, которая запрашивает данные для уведомлений наших клиентов.Мы хотели, чтобы сервис обрабатывал данные быстрее.В настоящее время наша существующая служба опрашивает и обрабатывает данные в одном потоке, что иногда вызывает задержку уведомлений на почасовой основе.Я планирую использовать 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. AmЯ правильно делаю?Хотел бы спросить несколько советов и плюсов и минусов по моей концепции.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Вы не можете регулировать пул потоков, но почему бы просто не иметь простой счетчик приращений / декрементов, который вы проверяете перед запуском нового потока?

В псевдокоде -

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 (), который сам уменьшает счетчик, предотвращая необходимость подключения вашего работника к классу myWorkLauncher.В качестве альтернативы вы можете заменить упрощенный Thread.Sleep на AutoResetEvent или аналогичный.

0 голосов
/ 13 сентября 2018

Вы должны проверить возвращаемое значение:

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

Невозможно обработать изменение из-за этого:

Вы не можете установить максимальное количество рабочих потоков или IЗавершение / O потоков до числа, меньшего, чем число процессоров на компьютере.Чтобы определить, сколько процессоров присутствует, извлеките значение свойства Environment.ProcessorCount.Кроме того, вы не можете установить максимальное количество рабочих потоков или потоков завершения ввода-вывода на меньшее, чем соответствующее минимальное количество рабочих потоков или потоков завершения ввода-вывода.Чтобы определить минимальный размер пула потоков, вызовите метод GetMinThreads.

См .: MSDN


Итак, вы можете сделать что-то вроде этого:

ThreadPool.SetMaxThreads(16, 16);

Но я предполагаюВы пытались подавить ThreadPool.В общем, это не очень хорошая идея.Вам понадобится альтернатива для такой логики.

Семафор может быть опцией, как описано здесь , или шаблон @Fildor описывает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...