Setting source of an Image control from Memory Stream using Non-UI thread in WPF

独自空忆成欢 提交于 2019-12-11 11:35:59

问题


I am Capturing image from a finger print Scanner and i want to display the captured image live in an Image control.

//Onclick of a Button
 Thread WorkerThread = new Thread(new ThreadStart(CaptureThread));
 WorkerThread.Start();

So i created a thread as above and called the method that captures the image from the device and sets the source of the Image control as follows.

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;
    }

Now when i Run the project it throws an Exception on line Action act = () => { imgLivePic.Source = imageSource; }; Saying "The Calling thread Can Not Access this object because a different thread owns it". i did some research and i found out that if i want to use UI controls over a NON-UI thread i should use Dispatcher.Invoke method, which as you can see i have but i am still getting the same exception. can someone please tell me what am i doing wrong?


回答1:


The BitmapImage does not necessarily need to be created in the UI thread. If you Freeze it, it will later be accessible from the UI thread. Thus you will also reduce the resource consumption of your application. In general, you should try to freeze all Freezables if possible, especially bitmaps.

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);
}



回答2:


The BitmapImage itself needs to be constructed on the Dispatcher thread.



来源:https://stackoverflow.com/questions/28558911/setting-source-of-an-image-control-from-memory-stream-using-non-ui-thread-in-wpf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!