我正在开发的C#应用程序主要涉及对来自相机的图像进行操作并将其打印在PictureBox上。它有一个用C++编写的库(imgcam),可以从网络摄像头中检索图像并复制它们(imgcam_copy),然后将它们传递给请求它们的托管代码。反过来,应用程序的托管部分由执行while循环的辅助线程组成,该循环从非托管库中获取图像并将其打印到PictureBox上。
一切都运行良好,最棘手的部分是从非托管到托管代码的动态资源管理,这方面我清楚地知道自己在做什么(至少我希望如此),但问题在于编写使线程正常工作所需的代码。实际上,在浏览了几个小时的网页之后,有许多事情对我来说还不清楚。
我被迫使用UI线程打印图像,因此必须依赖Invoke。
一切都运行良好,最棘手的部分是从非托管到托管代码的动态资源管理,这方面我清楚地知道自己在做什么(至少我希望如此),但问题在于编写使线程正常工作所需的代码。实际上,在浏览了几个小时的网页之后,有许多事情对我来说还不清楚。
我被迫使用UI线程打印图像,因此必须依赖Invoke。
delegate void setImageCallback(Image img);
private void showFrame(Image img)
{
if (pboxCam.InvokeRequired)
{
this.Invoke(new setImageCallback(showFrame), img);
}
else
{
pboxCam.Image = img;
}
}
我有很多问题:
1)Invoke是一个昂贵的操作吗? 我尽力减少对图像主要操作的执行时间,但是在显示结果时浪费部分收益会让人失望。
2)您认为是使用同步Invoke还是异步BeginInvoke + 图像复制更好?
3)将图片作为函数参数而不是访问类成员可能有帮助吗?
private delegate void setImageCallback();
private void showFrame()
{
if (pboxCam.InvokeRequired)
{
this.Invoke(new setImageCallback(showFrame));
}
else
{
pboxCam.Image = cm.bitmap;
}
}
4)也许你不会担心性能问题,但我想知道你是否关心线程安全问题。UI线程只想显示一张图片,而非UI线程则在复制它,依赖于异步机制真的不安全吗?
BeginInvoke
的问题的方法是手动限制自己的请求,这样如果图像没有在你有新图像要显示的时候被重新绘制,你就跳过除最新请求之外的所有请求。这样UI不会落后于处理,其他UI事件仍然不需要等待超过一个重绘时间才能到达队列的前面。当然,这种限制并不是非常容易管理的,至少没有像Rx这样的框架帮助。 - Servy