Updating an Image UI property from a BackgroundWorker thread

北城余情 提交于 2019-12-04 17:45:05
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.

A control (Image) can only be changed on the Thread which created it. So essentially what happens is your background thread changes the property on your object, which in turn fires the PropertyChanged event, which is then consumed by WPF, which then attempts to modify the Image control (remember we're still on the BackgroundThread throughout this chain of events).

Luckily, the fix is pretty simple:

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  myWindow.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate() 
     {
        this.CurrentImage = (TransformedBitmap)e.Result;
        ....
     });
}

You will need a reference to your Window or Control for this to work, but this essentially queues up the delegate to run on the UI thread instead of the background thread.

Only dispatcher is allowed to interact with the UI. Have a look here:

http://www.jeff.wilcox.name/2010/04/propertychangedbase-crossthread/

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!