Некоторые теги отсутствуют в моем приложении, использующем пул потоков

#c# #multithreading #asynchronous #threadpool #rfid

Вопрос:

У нас есть настольное приложение, основная цель которого-поймать все метки, считываемые с RFID-считывателей разных брендов. Мы подключаем считыватели и устанавливаем ThreadPool , например, подключенный считыватель. Все работает довольно хорошо, когда подключено 4 или 5 считывателей. Проблема возникает, когда подключено почти 30 считывателей. Многие теги отсутствуют. Эти метки присутствуют в каждом транспортном средстве. Эти автобусы будут заходить в наземный терминал, так что у нас есть считыватели в каждой зоне, тогда мы сможем рассчитать счета. С другой стороны, 8 или 10 автобусов будут заходить в терминал каждую минуту и будут проходить через большинство читателей. Мой вопрос в том, ThreadPool эффективен ли он в этом случае, или мне следует использовать другую технику?

Вот фрагмент моего кода:

 Client = new TcpClient(pIPReader, pPuerto);
if (Client.GetStream().CanRead)
{
    RX = new StreamReader(Client.GetStream());
    ThreadPool.QueueUserWorkItem(SocketNedapupPass, new object[] { 
    pIPReader,row.Cells[3].Value.ToString().ToUpper(), RX });
}

private void SocketNedapupPass(object obj)
{
        object[] array = obj as object[];
        bool lecturaNueva = false;

        HttpClient client = new HttpClient();
        HttpResponseMessage response = new HttpResponseMessage();
        StreamReader SR = (StreamReader)array[2];
       
        string pIPReader = array[0].ToString();
     
        if (SR.BaseStream.CanRead)
        {               
            try
            {                  
                while(SR.BaseStream.CanRead == true)
                {
                   string RawData = SR.ReadLine();
                  
                    if ((RawData.Length - 1) > InicioNedap)
                    {
                        string checkRawData = RawData.Substring(InicioNedap);

                        if (checkRawData.Length >= LongitudNedap)
                        {
                            RawData = checkRawData.Substring(0, LongitudNedap);

                            lecturaNueva = validacionLectura(RawData, 1, pIPReader);
                        }
                        else
                        {
                            oLog.WriteSuceso("La placa "   RawData   " no cumple con las 
                            longitudes especificadas en el archivo de configuración");
                        }
                    }
                   
                    if (lecturaNueva)
                    {
                        if (callAccion amp;amp; spAccion.Length >= 4)
                        {

                                        int codAntena = 1;

                                        if (listaReaderPrincipal.Any(x =>x.serie_punto_control 
                                          == pIPReader amp;amp; x.es_principal == "2"))
                                        {
                                            //PROCESAR SALIDA PRINCIPAL
                                            ProcesoSalidaPrincipalVehiculo(RawData, pIPReader, 
                                            codAntena, SR);//RX);
                                        }
                                        else if (listaReaderPrincipal.Any(x => 
                                        x.serie_punto_control == pIPReader amp;amp; x.es_principal 
                                         == "1"))
                                        {
                                            //PROCESAR INGRESO PRINCIPAL
                                            ProcesoIngresoPrincipalVehiculo(RawData, 
                                            pIPReader, codAntena, SR);//RX);
                                        }
                                        else
                                        {
                                            int res = cnAccion.EjecutarSP(spAccion, RawData, 
                                            codigoAlterno, pIPReader, codAntena);
                                        }
                            }
                            catch (Exception ex)
                            {
                                oLog.WriteError(ex);
                            }
                        }
                    }

                }

            }

            catch (Exception ex)
            {
                SR.Close();
                oLog.WriteError(ex);
            }
        }
    }
 

Комментарии:

1. Вы спрашиваете об эффективности ThreadPool , в то время как ваша проблема, похоже, связана с правильностью. Вы ищете более эффективную технику, чтобы быстрее получать более неправильные результаты?

2. Я ищу более эффективную технологию, чтобы не пропустить ни одного тега, потому что, похоже, у threadpool есть некоторые ограничения, вот мой ответ

3. А, ладно, теперь я понял.

Ответ №1:

Он ThreadPool предназначен для большого числа краткосрочных задач, чтобы амортизировать затраты Thread на создание и уничтожение. Если вашей программе требуется определенное количество длительных потоков, лучше создавать эти потоки явно с помощью Thread конструктора, а не полагаться на ThreadPool . Проблема с использованием ThreadPool для длительных задач заключается в том, что он может быть насыщен (в нем заканчиваются рабочие потоки), и в этом случае новые запросы на работу не удовлетворяются немедленно, а вместо этого они запланированы на более поздний срок. Каждой запланированной работе придется подождать, пока не завершатся некоторые из текущих задач. Если ни одна из выполняемых задач не завершается достаточно быстро, в ThreadPool пул вводятся новые потоки с частотой около одного нового потока в секунду (начиная с .NET5). Алгоритм внедрения является недокументированной деталью реализации, и он может измениться в более поздних версиях .NET. Единственный контроль, который у вас есть в настоящее время над этим алгоритмом, — это SetMinThreads метод. С помощью этого метода вы можете настроить, сколько потоков будет создано мгновенно по требованию, прежде ThreadPool чем переключиться на медленный, консервативный алгоритм. Вы можете установить этот порог так высоко, как хотите, в начале программы, например:

 ThreadPool.SetMinThreads(1000, 1000);
 

…но в этом случае цель ThreadPool завещания в значительной степени была побеждена, и ThreadPool его уже вряд ли можно было бы назвать пулом.

Комментарии:

1. спасибо за разъяснение, я постараюсь работать так, как вы предлагаете.