В моей программе есть класс BackgroundWorker, который предварительно загружает изображения в объект BitmapImage. Мне нужно передать это предварительно загруженное изображение в основное приложение (WPF), где оно будет скопировано в другой объект BitmapImage. Это, кажется, работает, когда я пытаюсь
imgViewer.Source = imgNext; //imgNext is a main app copy of the preloaded image
возникает ошибка, означающая, что этот объект (imgNext) принадлежит другому потоку и его нельзя использовать.
Есть идеи, как избавиться от этого и заставить работать код?
Спасибо всем за ответы!
На самом деле мне удалось решить эту проблему, создав статический BitmapImage
внутри App
класса.
Перед его использованием я делаю
App.iNext = null;
Затем я загружаю фактическое изображение и замораживаю его, чтобы к этому статическому свойству можно было получить доступ из любого места. Когда цикл повторяется много раз, присвоение нуля предотвращает ошибки «объект заморожен».
И, конечно, было много работы по управлению одним экземпляром BGW, задачам очередей и т. Д.
(В настоящее время я использую класс ImagesContainer, определенный также в моей программе, который имеет два свойства BitmapImage. Я использую его для получения предварительно загруженных изображений от backgroundworker.)
imgNext - публичная переменная, определенная в MainWindow. (основная тема)
void bwImgLoader_DoWork(object sender, DoWorkEventArgs e)
{
backgrLoadNextPrevList list = e.Argument as backgrLoadNextPrevList;
ImagesContainer result = new ImagesContainer();
if (list.HasNextPath) result.imgPrev = PrepareImage(list.NextPath);
if (list.HasPrevPath) result.imgNext = PrepareImage(list.PrevPath);
e.Result = result;
}
void bwImgLoader_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
ImagesContainer result = e.Result as ImagesContainer;
if (result.imgNext != null)
{
setNextDelegate s = new setNextDelegate(setNext);
object[] t = { result.imgNext };
imgNext.Dispatcher.Invoke(s, t);
}
// do not take into account this line, just ignore it.
//if (result.imgPrev != null) imgPrev = result.imgPrev;
}
public void setNext(BitmapImage b)
{
imgNext = b;
}
public delegate void setNextDelegate(BitmapImage b);
Замораживание растрового изображения помогает только при первой фоновой загрузке (см. Комментарий под ответом ниже). Когда я вызываю BackgroundWorker во второй раз, возникает ошибка, что объект заморожен и не может быть изменен. Есть ли способ разморозить его?
Или есть ли способ скопировать данные из одного потока в другой, не копируя указание на поток?
ОБНОВЛЕНО
Спасибо всем за ответы!
На самом деле мне удалось решить эту проблему, создав статический BitmapImage
внутри App
класса.
Перед его использованием я делаю
App.iNext = null;
Затем я загружаю фактическое изображение и замораживаю его, чтобы к этому статическому свойству можно было получить доступ отовсюду. Когда цикл повторяется много раз, присвоение нуля предотвращает ошибки.
И, конечно, было много работы по управлению отдельным экземпляром BGW, задачам очередей и т. Д.
Но эти усилия стоили результата - я получил + 125% производительности !!! Спасибо всем!