我正在从一个指纹扫描仪捕捉图像,我想在一个图像控件中实时显示捕捉的图像。
//Onclick of a Button
Thread WorkerThread = new Thread(new ThreadStart(CaptureThread));
WorkerThread.Start();
所以我按照上面的方法创建了一个线程,并调用了从设备上捕捉图像的方法,并设置了图像控件的来源,如下所示。
private void CaptureThread()
m_bScanning = true;
while (!m_bCancelOperation)
GetFrame();
if (m_Frame != null)
MyBitmapFile myFile = new MyBitmapFile(m_hDevice.ImageSize.Width, m_hDevice.ImageSize.Height, m_Frame);
MemoryStream BmpStream = new MemoryStream(myFile.BitmatFileData);
var imageSource = new BitmapImage();
imageSource.BeginInit();
imageSource.StreamSource = BmpStream;
imageSource.EndInit();
if (imgLivePic.Dispatcher.CheckAccess())
imgLivePic.Source = imageSource;
Action act = () => { imgLivePic.Source = imageSource; };
imgLivePic.Dispatcher.BeginInvoke(act);
Thread.Sleep(10);
m_bScanning = false;
现在当我运行这个项目时,它在Action act = () => { imgLivePic.Source = imageSource; };
一行抛出了一个异常,说"调用线程不能访问这个对象,因为不同的线程拥有它"。
我做了一些研究,发现如果我想在一个非UI线程上使用UI控件,我应该使用Dispatcher.Invoke方法,正如你所看到的,我已经这样做了,但我仍然得到同样的异常。
谁能告诉我我做错了什么吗?
BitmapImage不一定需要在UI线程中创建。如果你
它,它以后就可以从UI线程访问。因此你也会减少你的应用程序的资源消耗。一般来说,如果可能的话,你应该尝试冻结所有的Freezables,特别是位图。
Freeze
using (var bmpStream = new MemoryStream(myFile.BitmatFileData)) imageSource.BeginInit(); imageSource.StreamSource = bmpStream; imageSource.CacheOption = BitmapCacheOption.OnLoad; imageSource.EndInit(); imageSource.Freeze(); // here if (imgLivePic.Dispatcher.CheckAccess()) imgLivePic.Source = imageSource; Action act = () => { imgLivePic.Source = imageSource; };