#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. спасибо за разъяснение, я постараюсь работать так, как вы предлагаете.