最近遇到客户使用三代开发库编写程序出现偶发性的软件闪退问题,通过观察电脑系统日志发现是这个ucrtbase.dll报错。一时间不知道问题点在哪,客户说自己软件打断电在执行下面一句话之后出现闪退问题。
EzdKernel.E3_ERR err = EzdKernel.E3_OpenFileToEntMgr(pathDoc, m_idEM1, false, false);
随后开始写demo,按照客户的加工逻辑编测试,一次偶然的加工点击停止复现除了问题。复现问题就好说了,随后证实是否是这个问题。
代码 如下 这个是简化过的流程代码
private void button_Start_Click(object sender, EventArgs e)
{
m_bStop = false;
threadWork = new Thread(async delegate ()
{
while (!m_bStop)
{
try
{
////LoadFile1(path1);
//Task.Run(() =>
//{
// button4_Click(null, null);
// m_bStop = true;
// threadWork?.Abort();
//});
AddLog("加载图档");
LoadDoc1(path1);
//LoadFile2(path2);
LoadDoc2(path2);
var t1 = Task.Run(() =>
{
AddLog($"card{1}加工");
GetFlyParam(m_idMarkerList[0], 40);
SetFly(m_idMarkerList[0], m_idEM1, m_idCurLayer1, m_IdEntList1, ref pf3D_FlyStartPos1, ref filelength1);
AddLog($"card{1}加工完成");
});
var t2 = Task.Run(() =>
{
AddLog($"card{2}加工");
GetFlyParam(m_idMarkerList[1], 40);
SetFly(m_idMarkerList[1], m_idEM2, m_idCurLayer2, m_IdEntList2, ref pf3D_FlyStartPos2, ref filelength2);
AddLog($"card{2}加工完成");
});
await Task.WhenAll(t1, t2);
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
});
threadWork.IsBackground = true;
threadWork.Start();
}
private void button_Stop_Click(object sender, EventArgs e)
{
button4_Click(null, null);
m_bStop = true;
threadWork?.Abort();
}
- 点击运行逻辑按钮立马点击停止,然后再次开启运行,就会出现闪退问题,并且偶发性特别高,分析代码
- 启动开启了一个线程,去加载图档,然后有开启了两个线程池去执行任务。
- 如果出现立马停止,存在stop在两个线程池之前就调用,线程池中的列表不会退出。
- 列表还在下发数据到板卡中,又点击启动,就又会重新加载图档,然后软件就闪退了。
总结:
列表在下发过程中,还未下发完成的时候,不能去加载新的图档,因为加载新的图档,会清空对象(图层,对象),然后下发还在继续,拿到的数据是不存在的,所以导致软件闪退。
还发现列表指令中振镜跳转,如果点pt3d未实例化,传入进去也会导致软件闪退,切记,编写代码一定要注意对象是否在内存空间存在(特别是c#调用c++)。