【问题标题】:Display WPF Image in backgroundworker在后台工作人员中显示 WPF 图像
【发布时间】:2011-02-09 09:42:37
【问题描述】:

我正在使用 WPF 3.5。

我在 backgroundworker_DoWork 事件中有 while 循环,它将不断从 DSLR 流式传输图像。

最初,流媒体图像将显示在 PictureBox 中

<Grid>
    <WindowsFormsHost VerticalAlignment="Top" Background="Transparent" Height="500">
        <wf:PictureBox x:Name="picLiveView" />
    </WindowsFormsHost>
</Grid>

下面是代码:

        while (!liveViewExit)
        {
            try
            {
                if (picImage != null)
                    lock (mylock)
                    {
                        this.picLiveView.Image = (Image)picImage.Clone();
                    }
            }
            catch
            {

            }
        }

这很好用。

但是,当我尝试将 PictureBox 更改为 WPF 图像控件时,将 BitmapImage 分配给 WPF 图像控件时出现此错误:

{“调用线程无法访问此对象,因为不同的线程拥有它。”}

        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
        {

        }

为什么 .NET 2 PictureBox 控件有效,而 .NET 3.5 WPF Image 控件无效?

我试过这段代码:

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*/);

它没有任何错误,但图像没有刷新。 while 循环使应用程序没有响应。

【问题讨论】:

标签: wpf picturebox


【解决方案1】:

你需要在主线程中实例化一个Dispatcher对象,并在后台worker中使用它,调用它的Invoke方法。

这是一个代码示例:

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*/);

【讨论】:

  • 这回答了“如何让它在 WPF 中工作?”问题,但没有回答为什么它适用于 WinForms。答案在于两种技术中 UI 线程管理的不同方法。我不确定@billy_flow 是否真的对后者感兴趣。
  • @Anvaka:好的,我会等待你的回答,详细描述这些差异。
  • @BertuPG:不,我赞成你的:)。我认为@billy_flow 确实对如何使其适用于 WPF 图像感兴趣,而不是对 WPF/WinForms 线程模型之间的差异感兴趣。添加评论以防我们都错了。
  • @Anvaka:谢谢 ;) 无论如何,尽管我知道“解决方法”(或更好:正确的方法),但我也对这些细节感兴趣。我会用谷歌搜索这个主题......再见!
  • @BertuPG:你为什么要搞乱Dispatcher 而不是设置BackgroundWorker.ReportsProgress 和处理ProgressChanged
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多