-->

在使用WPF非UI线程设置从内存流的图像控制的源(Setting source of an Imag

2019-09-27 14:55发布

我从一个指纹扫描仪捕获图像,我想显示拍摄的图像实时在Image控件。

//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;
                    }
                    else
                    {
                        Action act = () => { imgLivePic.Source = imageSource; };
                        imgLivePic.Dispatcher.BeginInvoke(act);
                    }
            }

            Thread.Sleep(10);
        }
        m_bScanning = false;
    }

现在,当我运行该项目它抛出上线一个异常Action act = () => { imgLivePic.Source = imageSource; }; Action act = () => { imgLivePic.Source = imageSource; }; 他说,“因为不同的线程拥有它调用线程不能访问这个对象 ”。 我做了一些研究,我发现,如果我想在一个非UI线程使用UI控件我应该使用Dispatcher.Invoke方法,正如你可以看到我有,但我仍然得到同样的异常。 有人可以告诉我什么我做错了什么?

Answer 1:

该BitmapImage的并不一定需要在UI线程创建。 如果您Freeze它,稍后是从UI线程访问。 因此,你也将减少应用程序的资源消耗。 在一般情况下,你应该尝试,如果可能的冻结所有Freezables,尤其是位图。

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;
}
else
{
    Action act = () => { imgLivePic.Source = imageSource; };
    imgLivePic.Dispatcher.BeginInvoke(act);
}


Answer 2:

BitmapImage本身需要在构造上Dispatcher线程。



文章来源: Setting source of an Image control from Memory Stream using Non-UI thread in WPF