闲倚葡萄架,醉卧温柔乡才是作者的生活态度。简单来说,就是作者最近迷上打游戏了,脑子空空,随便写写项目中使用C#的一些小技巧,不定时更新。
1.关于Task类和Tread类,很明显,他们都是微软提供给开发者控制线程的类,理论上Task类应该用得更多,甚至百度上搜C#多线程都是介绍Task类的。
但是,作者所在的公司,MES系统是基于.NET 3.5框架的。由于 .NET 3.5下并没有官方实现的 Task 库,所以系统中关于多线程的代码多是用Tread类实现。
介绍一下背景,公司日常生产中遇到一个BUG,发现某些电池的电压值不存在于系统中,经排查,原生文件中有该电压值,只是代码获取不到。
原代码(伪)为:
//打开数据流
//循环声明线程去获取文件里的电压值,假设资源足够,暂时也没遇到过资源不足的情况
//假设已存在getCellData方法
for(int i =0;i<file.count;i++)
{
Tread tread = new Tread(()=>getCellData());
tread.start;
}
//关闭数据流
-----------------------------------------------------------------------------------------分割线-----------------------------
以上代码,运行了好几年一直非常稳定,但是,突然有一天发现某个文件的电芯值取不了了,这个文件比其他文件的内容要大
后面经排查发现,其他线程跑完的时候,关闭了数据流,因为用的是同一个数据库对象,所以这个跑得慢的线程就没法把数据写入数据库了,增加一段代码解决
改进后代码(伪)
//打开数据流
//循环声明线程去获取文件里的电压值,假设资源足够,暂时也没遇到过资源不足的情况
//假设已存在getCellData方法
List<Tread > listTread = new List<Tread >();
for(int i =0;i<file.count;i++)
{
Tread tread = new Tread(()=>getCellData());
listTread.Add(tread);
tread.start;
}
foreach(Tread trd in listTread)
{
trd.Join();
}
//关闭数据流
关于以上代码,Join方法的作用是等待所有分支线程完成后,再由主线程去关闭数据流,故解决此次问题。
--------------------------------------------------2023.12.24-------------------------------------------------------