移除DalsaCamera时C#程序卡顿(Freeze)原因排查
问题:移除DalsaCamera时程序卡顿冻结
执行以下移除DalsaCamera的代码时,程序出现卡顿(Freeze)现象,相关代码如下:
移除相机的核心代码
removeCount = this.cameras.RemoveAll(delegate (DalsaCamera camera) { bool dead = camera.isDead(); if (dead) { camera.destroyObjects(); camera.disposeObjects(); if (controls.Contains(camera.ImageView)) { this.controls.Remove(camera.ImageView); camera.ImageView.Dispose(); } } return dead; });
DalsaCamera的destroyObjects方法
public void destroyObjects() { if (m_Xfer != null && m_Xfer.Initialized) m_Xfer.Destroy(); if (m_View != null && m_View.Initialized) m_View.Destroy(); if (m_Buffers != null && m_Buffers.Initialized) m_Buffers.Destroy(); if (m_AcqDevice != null && m_AcqDevice.Initialized) m_AcqDevice.Destroy(); }
说明:所用相机为DalsaCamera,m_Xfer、m_Buffers、m_AcqDevice属于SaperaLT库;图像显示控件为PictureBox。
卡顿原因分析
- UI线程被耗时硬件操作阻塞:这段移除相机的代码大概率在UI线程执行,而
destroyObjects里调用的SaperaLT库Destroy方法(比如m_AcqDevice.Destroy()、m_Xfer.Destroy())是同步的硬件资源销毁操作——这类操作需要和相机硬件通信、释放内核态采集资源,本身耗时较长。UI线程被这类操作占用时,无法及时处理界面刷新、用户输入等消息,直接导致程序卡顿冻结。 - UI控件销毁叠加耗时:
PictureBox.Dispose()属于UI控件销毁操作,虽然单独耗时不长,但叠加在硬件资源销毁之后,会进一步增加UI线程的占用时间,加剧卡顿。 - RemoveAll全程在UI线程同步执行:
List<T>.RemoveAll的委托逻辑会在调用线程(此处为UI线程)内同步完成,整个遍历相机列表、判断状态、销毁资源、移除控件的流程没有异步处理,一旦出现耗时操作,界面必然卡住。
内容的提问来源于stack exchange,提问作者Mandoo
相关产品推荐
相关产品推荐

