Проблема с WPF / BackgroundWorker и BitmapSource - PullRequest
5 голосов
/ 24 января 2010

Я новичок в WPF и пробую домашний проект, чтобы ознакомиться с этой технологией. У меня есть простая форма, где пользователь выбирает файл изображения, затем я отображаю данные EXIF ​​вместе с миниатюрой изображения. Это работает нормально, но когда я выбираю файл изображения RAW (~ 9 МБ), может возникнуть небольшая задержка при загрузке большого пальца, поэтому я подумал, что могу использовать BackgroundWorker для декодирования изображения, и пользователь сможет просматривать данные EXIF, а затем когда изображение было декодировано, оно отображается.

Объект BitmapSource объявлен в методе BackgroundWorkers DoWork:

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

Проблема, с которой я сталкиваюсь, заключается в том, что при попытке установить источник моего элемента управления Image в методе RunWorkerCompleted я получаю сообщение об ошибке, поскольку объект принадлежит другому потоку.

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

Я пытался использовать метод imgThumb.Dispatcher.BeginInvoke() для установки источника, но это тоже не сработало, я думаю, это из-за того, что args.Result принадлежит другому потоку, а не imgThumb? Как я могу обойти это?

Возможно, я неправильно запрограммировал свой Диспетчер (следующее из памяти, я удалил то, что имел).

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

Любые предложения или идеи приветствуются.

Обновление

Изменил мой метод DoWork для использования BitmapCreateOptions.None вместо .DelayCreation, но теперь при загрузке файлов RAW появляется следующая ошибка (файлы Canon .CR2 - все, что я тестировал на сегодняшний день), код отлично работает для jpg. Может ли это быть проблемой с установленным кодеком Canon, который позволяет мне отображать файлы RAW?

Приложение называется интерфейсом это было назначено для другого нить. (Исключение из HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

Ответы [ 2 ]

8 голосов
/ 24 января 2010

Вызовите Freeze () для BitmapSource, и у вас не возникнет этой проблемы (Freezing снимает ограничения с потоков, но делает объект неизменным)

2 голосов
/ 14 декабря 2011

У меня была проблема с образцом, и мне посчастливилось ее решить.

Краткий ответ: заверните в WriteableBitmap. Это за небольшую цену, ты.

Длинный ответ .

...