开发环境:
IDE:VS2022,
C#版本 >=.net4.0(4.0开始支持Task类)
内容:
有次做了一个20工位相互独立的上位机,使用Task类针对每个工位的流程单独开启一个线程,起初认为单个线程的任务处理完成,线程会自动释放,没有强制垃圾收集。
在二代I7CPU平台测试时,程序进程CPU占用最高50个线程左右(工位全部运行时,CPU总占用率一直维持在100%)这个线程数量和程序中明确使用的线程数量相仿,认为可能是CPU版本较低导致,随更换为9代I7CPU,经测试工位全部运行时,程序进程CPU线程数最高100左右,CPU总占用率仍然达到100%,随考虑优化线程使用,最终在线程结束时加了一个GC.Collect()解决问题。代码示例如下:
//有问题代码
任务1:
private void ReadStartTask()
{
while(_IsRuning)
{
for(int i=0;i<20;i++) //总共20个工位
{
if(ScanEnable[i]) //每个工位是否可以开始扫码,开始流程
{
Task.Factory.StartNew((obj) => {
int n = (int)obj;
StartScan(n);
},i); //传入工位编号
}
}
Thread.Sleep(10);
}
}
private void StartScan(int station)
{
bool done =false;
while(!done)
{
switch(ScanFlow[station]) //不同工位进行处理
{
case ScanFlow.ScanSN:
break;
case ScanFlow.ScanEnd:
done=true;
break;
}
Thread.Sleep(100);
}
}
//优化后代码
任务1:
private void ReadStartTask()
{
while(_IsRuning)
{
for(int i=0;i<20;i++) //总共20个工位
{
if(ScanEnable[i]) //每个工位是否可以开始扫码,开始流程
{
Task t=new Task((obj) => {
int n = (int)obj;
StartScan(n);
},i); //传入工位编号
t.ContinueWith(f=>{
GC.Collect();
});
t.Start();
}
}
Thread.Sleep(10);
}
}
private void StartScan(int station)
{
bool done =false;
while(!done)
{
switch(ScanFlow[station]) //不同工位进行处理
{
case ScanFlow.ScanSN:
break;
case ScanFlow.ScanEnd:
done=true;
break;
}
Thread.Sleep(100);
}
}