WPF/BackgroundWorker and BitmapSource problem

北城以北 提交于 2019-12-06 03:10:49

问题


I am a beginner with WPF and trying a home project to become familiar with the technology. I have a simple form where the user selects an image file, I then display EXIF data along with a thumbnail of the image. This is working fine but when I select a RAW image file (~9 MB) there can be a slight delay while the thumb loads, so I thought I could use the BackgroundWorker to decode the image and the user can view the EXIF data, then when the image has been decoded it is displayed.

The BitmapSource object is declared in the BackgroundWorkers DoWork method:

worker.DoWork += delegate(object s, DoWorkEventArgs args)
{
    string filePath = args.Argument as string;

    BitmapDecoder bmpDecoder = BitmapDecoder.Create(new Uri(filePath), BitmapCreateOptions.None, BitmapCacheOption.None);
    BitmapSource bmpSource = bmpDecoder.Frames[0];
    bmpSource.Freeze(); //As suggested by Paul Betts

    args.Result = bmpSource;
};

the problem that I'm running into is when I try to set the source of my Image control in the RunWorkerCompleted method I receive an error because the object is owned by another thread.

worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
{
    imgThumb.Source = args.Result as BitmapSource;
};

I tried using the imgThumb.Dispatcher.BeginInvoke() method to set the source but this didn't work either, I guess it's because it's the args.Result that is owned by another thread, and not the imgThumb? How can I get round this?

It could be that I was coding my Dispatcher wrong (the following is from memory, I deleted what I had).

imgThumb.Dispatcher.Invoke(new Action<BitmapSource>(
    delegate(BitmapSource src)
    {
        imgThumb.Source = src;
    }
), bmpSource);

Any suggestions or ideas are welcome.

Update

Changed my DoWork method to use BitmapCreateOptions.None rather than .DelayCreation but now I get the following error when loading RAW files (Canon .CR2 files is all I have tested to date), the code works fine for jpg's. Could this be an issue with the Canon Codec I installed to allow me to display the RAW files?

The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))


回答1:


Call Freeze() on the BitmapSource and you won't have this problem (Freezing gets rid of the threading restrictions, but makes the object immutable)




回答2:


I had exactly the sample problem and was lucky to solve it.

Short answer: wrap in WriteableBitmap. That comes at a little price, thou.

Long answer.



来源:https://stackoverflow.com/questions/2128438/wpf-backgroundworker-and-bitmapsource-problem

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