Я просто смотрел на это и должен был добавить свои два цента, правда, через несколько лет после первоначального поста (на тот случай, если кто-нибудь еще будет искать ту же самую вещь, которую я изучал).
У меня есть элемент управления Изображение , которому необходимо загрузить свое изображение в фоновом режиме, используя Stream , а затем отобразить.
Проблема, с которой я продолжал сталкиваться, заключается в том, что BitmapSource , его источник Stream и элемент управления Image должны были находиться в одном потоке.
В этом случае, используя Binding и установив его IsAsynch = true, будет возникать перекрестное исключение потока.
BackgroundWorker отлично подходит для WinForms, и вы можете использовать его в WPF, но я предпочитаю избегать использования сборок WinForm в WPF (раздувание проекта не рекомендуется, и это тоже хорошее практическое правило). В этом случае это также должно вызвать недопустимое исключение перекрестной ссылки, но я не проверял его.
Оказывается, что одна строка кода сделает любую из этих работ:
//Create the image control
Image img = new Image {HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch, VerticalAlignment = System.Windows.VerticalAlignment.Stretch};
//Create a seperate thread to load the image
ThreadStart thread = delegate
{
//Load the image in a seperate thread
BitmapImage bmpImage = new BitmapImage();
MemoryStream ms = new MemoryStream();
//A custom class that reads the bytes of off the HD and shoves them into the MemoryStream. You could just replace the MemoryStream with something like this: FileStream fs = File.Open(@"C:\ImageFileName.jpg", FileMode.Open);
MediaCoder.MediaDecoder.DecodeMediaWithStream(ImageItem, true, ms);
bmpImage.BeginInit();
bmpImage.StreamSource = ms;
bmpImage.EndInit();
//**THIS LINE locks the BitmapImage so that it can be transported across threads!!
bmpImage.Freeze();
//Call the UI thread using the Dispatcher to update the Image control
Dispatcher.BeginInvoke(new ThreadStart(delegate
{
img.Source = bmpImage;
img.Unloaded += delegate
{
ms.Close();
ms.Dispose();
};
grdImageContainer.Children.Add(img);
}));
};
//Start previously mentioned thread...
new Thread(thread).Start();