Я пытаюсь загрузить изображение в фоновом режиме, а затем обновить интерфейс. Я играю с этим весь день, и я не знаю, чего мне не хватает. Я получаю следующее сообщение об ошибке:Как загружать изображения в фоновом режиме?
"The calling thread cannot access this object because a different thread owns it."
Я охотился вокруг, следуя примеру после того, как, например, но я не могу найти ответ. Я также завернул код, касающийся пользовательского интерфейса в другом BeginInvoke.
Обновление 3: Мораль истории. ImageSource не является потокобезопасным для доступа.
Обновление 2: Это должно быть простым решением :). Я попробовал клонирование, но это не привело к успеху, но я получил другую ошибку: «Исключение было вызвано целью вызова».
Обновление 1: Я попробовал BackgroundWorker, но я все еще получаю ту же ошибку, но это происходит на brush.ImageSource.Height. Я правильно сигнализирую интерфейс? Какие-либо предложения?
Вот мой XAML:
<Window x:Class="Slideshow.Show"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
<Canvas Background="Black" Name="canvas">
<Viewbox Name="background" Stretch="Uniform">
<Rectangle name="background" />
</Viewbox>
</Canvas>
</DockPanel>
</Window>
Вот некоторые из кода позади:
namespace Slideshow
{
public class Show
{
public Show()
{
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync();
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BitmapSource bitmap = e.Result as BitmapSource;
if (bitmap != null)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal
(ThreadStart)delegate()
{
Image image = new Image();
image.Source = bitmap;
background.Child = image;
});
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
BitmapSource bitmapSource = CreateBrush(GetRandomFile());
e.Result = bitmapSource;
}
}
}
Попробуйте удалить часть Dispatcher.BeingInvoke. Весь смысл BackgroundWorker заключается в том, что событие автоматически переводится в поток пользовательского интерфейса для вас, поэтому вам не нужно беспокоиться. – Samuel
Проблема заключалась в том, что ImageSource не гарантируется потокобезопасность, поэтому все умрет. Как только я заменил это с помощью BitmapSource, моя проблема была решена! – kevindaub