Reputation: 81
I am using WPF 3.5.
I have while loop in a backgroundworker_DoWork event, which will continuously stream images from a DSLR.
Initially, the streamed image will be displayed in a PictureBox
<Grid>
<WindowsFormsHost VerticalAlignment="Top" Background="Transparent" Height="500">
<wf:PictureBox x:Name="picLiveView" />
</WindowsFormsHost>
</Grid>
Here is the code behind:
while (!liveViewExit)
{
try
{
if (picImage != null)
lock (mylock)
{
this.picLiveView.Image = (Image)picImage.Clone();
}
}
catch
{
}
}
This works fine.
However, when I try to change the PictureBox to WPF Image control, I have this error when I assigned the BitmapImage to the WPF image control:
{"The calling thread cannot access this object because a different thread owns it."}
MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
ms.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
try
{
if (bi != null)
{
this.imageBox.Source = bi;
}
}
catch
{
}
Why the .NET 2 PictureBox control works while .NET 3.5 WPF Image control doesn't?
I tried this code:
BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
// load your data
disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);
It doesn't have any error, but the image doesn't refresh. The while loop make the application not responding.
Upvotes: 0
Views: 3415
Reputation: 653
you need to instantiate a Dispatcher object in main thread, and use it in the background worker, calling it's Invoke method.
Here's a sample of code:
BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
// load your data
disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);
Upvotes: 2