dotnet中线程资源独占UI元素,不能跨线程访问,可以通过Dispatcher.Invoke的方式调用,但实际处理还是UI线程中,任务量比较大的数据会增加线程的处理压力。 其实还有一种做法,可以通过设置UI元素为只读的方式,跨线程访问。 如BitmapSource跨线程访问,可以调用Freeze设置元素为只读模式。 Aforge.net跨线程传递图像资源,如下:
private void Cam_NewFrame(object sender, AForge.Video.NewFrameEventArgs eventArgs)
{
if (m_SingleScaleImage)
{//全屏
if (m_Index >= ManagerCam.inst().Count) m_Index = 0;
Camfi camera = ManagerCam.inst()[m_Index];
if (camera.device != sender) return;//不匹配设备退出
IntPtr hBitmap = eventArgs.Frame.GetHbitmap();
BitmapSource image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap,
IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
Dispatcher.Invoke(new Action(() =>
{
gallery_single_image.Source = BitmapFrame.Create(image);
}));
GC.Collect();
GC.WaitForPendingFinalizers();
//释放资源
if (!DeleteObject(hBitmap))
throw new System.ComponentModel.Win32Exception();
}
else
{//显示所有摄像头
Camfi camera = ManagerCam.inst().Where(o => o.device == sender).First();
if (camera == null) return;//没有找到设备退出
IntPtr hBitmap = eventArgs.Frame.GetHbitmap();
BitmapSource image = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap,
IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
image.Freeze();
Dispatcher.Invoke(new Action(() =>
{
camera.imageBox.Source = image;
}));
GC.Collect();
GC.WaitForPendingFinalizers();
//释放资源
if (!DeleteObject(hBitmap))
throw new System.ComponentModel.Win32Exception();
}
}