如何在多线程WPF应用程序中显示更改的图像?

时间:2016-04-05 15:31:33

标签: c# wpf multithreading image

我正在开展一个项目,我们需要捕捉和处理图像以控制机器人。这两件事情都很好。

我似乎能够弄清楚如何使用WPF来显示预处理和后处理图像。

我有一个使用此代码的应用:

public CamNotification(string label1, string label2, BitmapSource image1, BitmapSource image2)

private bool hwLink_SetInfos(CamNotification info)
{
    try
    {
        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
        {
            lblText1.Content = info.Label1;
            lblText2.Content = info.Label2;

            ImageBox1.Source = info.Image1;
            ImageBox2.Source = info.Image2;
            InvalidateVisual();
        }));
        return true;
    }
    catch (Exception ex)
    {
        Debugger.Break();
        return false;
    }
}

它会更改描述图像的标签和' image.source' s。

它的工作原理 - > fine< - 当我使用WPF按钮来调用代码时,但当我尝试使用Threadpool中的WorkerThread替换两个' image.source&时#39; s即使标签是,也不显示图像。

此外,如果我已按下按钮并显示图片,则来自 - > WorkerThread< - 的调用最终会在MainThread中删除图像并留下空白区域而不是更新他们对新内容。

使用Dispatcher我已经删除了所有的crossthead问题,标签已更新但是" PresentationFramework - > System.Windows.Controls.Image"很清楚,没有更新:-(

在查看stackoverflow时,我发现了这个问题:

WPF imaging problems

似乎关注与我类似的问题。然而,答案和OP都没有评论他如何解决他的问题,这对我有帮助。

我很感激你能给我的任何帮助。

1 个答案:

答案 0 :(得分:0)

BitmapImageSource是一个可冻结的对象,如果您打算通过线程访问它,应该将其冻结

来自MSDN

  

Freezable提供Changed事件以通知观察者任何事件   对对象的修改。冻结Freezable可以改善它   性能,因为它不再需要在变更上花费资源   通知。冻结的Freezable也可以在线程之间共享,   而一个解冻的Freezable则不能。

...

  

freezable的Freeze方法可让您禁用此自我更新   能力。您可以使用此方法使画笔变为“冻结”或   不可修改的。

当您处理另一个线程上的图像时,您需要更改代码以调用Freeze(),然后才能在UI线程上使用它。下面的一些工作代码

public CamNotification(string label1, string label2, BitmapSource image1, BitmapSource image2)

private bool hwLink_SetInfos(CamNotification info)
{
    try
    {
        info.Image1.Freeze();
        info.Image2.Freeze();

        Application.Current.Dispatcher.BeginInvoke((Action)(() =>
        {
            lblText1.Content = info.Label1;
            lblText2.Content = info.Label2;

            ImageBox1.Source = info.Image1;
            ImageBox2.Source = info.Image2;
            InvalidateVisual();
        }));
        return true;
    }
    catch (Exception ex)
    {
        Debugger.Break();
        return false;
    }
}

一些相关文章:

How do you pass a BitmapImage from a background thread to the UI thread in WPF?

In what scenarios does freezing WPF objects benefit performance greatly?