从一个BackgroundWorker线程更新图像UI属性 [英] Updating an Image UI property from a BackgroundWorker thread

查看:981
本文介绍了从一个BackgroundWorker线程更新图像UI属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个WPF应用程序我写,我有这势必会在UI图像对象TransformedBitmap属性。每当我更改此属性,图像被更新(从而被显示的图像在屏幕上被更新)。为了防止冻结或不响应,而我检索下一个图像用户界面,我试图快照检索,像这样一个BackgroundWorker:

 私人无效bw_DoWork(对象发件人,DoWorkEventArgs E)
{
e.Result = this.snapshotHelper.GetSnapshot(ImageFormat.Bmp);
}



然后,在我RunWorkerCompleted方法,我有以下几点:

 私人无效bw_RunWorkerCompleted(对象发件人,RunWorkerCompletedEventArgs E)
{
this.CurrentImage =(TransformedBitmap)e.Result;
....
}

这似乎是工作好,直到上用来告诉图像对象更新,当我更新CurrentImage财产NotifyPropertyChanged方法;我得到一个跨线程错误

 公共事件PropertyChangedEventHandler的PropertyChanged; 
私人无效NotifyPropertyChanged(字符串信息)
{
如果(的PropertyChanged!= NULL)
{
//下面会导致调用线程不能访问该对象因为不同的线程拥有它错误!
的PropertyChanged(这一点,新PropertyChangedEventArgs(信息));
}
}



我真的不知道该如何改变周围的事物或做什么不同的来解决这个错误。我一直在阅读有关BackgroundWorkers在过去的几个小时,在我看来,我应该能够设置在RunWorkerCompleted方法CurrentImage罚款;从我可以告诉最少。任何的帮助将不胜感激! !谢谢


解决方案

  Dispatcher.Invoke((动作< TransformedBitmap>)(OBJ => ; this.CurrentImage = OBJ),e.Result为TransformedBitmap); 

这应该工作...



更新



在你的情况,你使用的是可冻结对象,问题是在你已经创建需要在发送之前被冻结的位图在UI线程。所以,你DoWork的将是如下:

 无效worker_DoWork(对象发件人,DoWorkEventArgs E)
{
VAR BMP = snapshotHelper.GetSnapshot(ImageFormat.Bmp);
bmp.Freeze();
e.Result = BMP;
}

然后在RunWorkerCompleted你像我上面写的更新属性。


In a WPF application I'm writing, I have a TransformedBitmap property which is bound to an Image object on the UI. Whenever I change this property, the Image is updated (and thus the image being displayed to the screen is updated). In order to prevent the UI from freezing or becoming unresponsive whilst I retrieve the next image, I'm attempting to the snapshot retrieval with a BackgroundWorker like this:

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
  e.Result = this.snapshotHelper.GetSnapshot(ImageFormat.Bmp);
}

then, in my RunWorkerCompleted method, I have the following:

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  this.CurrentImage = (TransformedBitmap)e.Result;
  ....
}

This seems to work okay until on the NotifyPropertyChanged method used to tell the Image object to update when I update the CurrentImage property; I get a cross-thread error.

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
  if (PropertyChanged != null)
  {
  //The following causes a "the calling thread cannot access this object because a different thread owns it" error!
    PropertyChanged(this, new PropertyChangedEventArgs(info));      
  }
}

I really don't know how to change things around or what to do differently to get around this error. I've been reading about BackgroundWorkers for the past couple of hours and it seems to me that I should be able to set CurrentImage fine in the RunWorkerCompleted method; at least from what I can tell. Any help on this would be greatly appreciated! Thanks!

解决方案

Dispatcher.Invoke((Action<TransformedBitmap>) (obj => this.CurrentImage = obj), e.Result as TransformedBitmap);

This should work...

Update

In your case you are using freezable object, and the problem is in the bitmap that you have created need to be freezed before sending it in UI thread. So you DoWork will be as follows:

void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            var bmp = snapshotHelper.GetSnapshot(ImageFormat.Bmp);
            bmp.Freeze();
            e.Result = bmp;            
        }

Then in RunWorkerCompleted you update the property as I wrote above.

这篇关于从一个BackgroundWorker线程更新图像UI属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆