c# - 使用 ThreadPool 我的应用程序缺少一些标签
问题描述
我们有一个桌面应用程序,其主要目标是捕获从不同品牌的 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 && spAccion.Length >= 4)
{
int codAntena = 1;
if (listaReaderPrincipal.Any(x =>x.serie_punto_control
== pIPReader && x.es_principal == "2"))
{
//PROCESAR SALIDA PRINCIPAL
ProcesoSalidaPrincipalVehiculo(RawData, pIPReader,
codAntena, SR);//RX);
}
else if (listaReaderPrincipal.Any(x =>
x.serie_punto_control == pIPReader && 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);
}
}
}
解决方案
ThreadPool
旨在用于大量短期任务,以摊销Thread
创建和销毁的成本。如果您的程序需要特定数量的长时间运行的线程,最好使用Thread
构造函数显式创建这些线程,而不是依赖ThreadPool
. 使用ThreadPool
for long running 任务的问题是它可能会变得饱和(它会耗尽工作线程),在这种情况下,新的工作请求不会立即得到满足,而是会被安排在以后进行。每个计划的工作都必须等到一些当前正在运行的任务完成。如果没有一个正在运行的任务足够快地完成,则ThreadPool
在池中注入新线程,频率约为每秒一个新线程(从 .NET 5 开始)。注入算法是一个未记录的实现细节,它可能会在以后的 .NET 版本中发生变化。您当前对该算法的唯一控制是SetMinThreads
方法。ThreadPool
使用这种方法,您可以配置在切换到缓慢、保守的算法之前按需立即创建多少线程。您可以在程序开始时将此阈值设置为任意高,例如:
ThreadPool.SetMinThreads(1000, 1000);
......但在这种情况下,遗嘱的目的在ThreadPool
很大程度上已经失败,并且ThreadPool
几乎不能再被描述为一个池。
推荐阅读
- ruby-on-rails-4 - 禁用 PATCH 的路由
- javascript - 摩卡异步钩子没有运行?
- html - favicon to base64 在此站点上失败
- c# - UIAutomation 方法 ElementFromPoint() 从 Windows 10 上的记事本中检索不正确的元素
- python - 在没有 PyPI 的情况下将具有依赖关系的 pip 包从本地目录安装到本地目录
- sql - Big Query SQL - 对所有可能的聚合级别进行分组
- php - PHP - 在 MySQL 查询中计算元素返回两倍的元素数量
- testng - 如果测试用例具有具有多个值的数据提供者,如何获取 Testng - 测试方法名称
- c# - C# 关闭此“关闭程序”弹出窗口
- highcharts - Highchart堆叠条yAxis堆叠标签问题