levanovd
levanovd

Reputation: 4165

BackgroundWorker vs NotifyPropertyChanged issue

I have WPF application that performs some calculations in BackgroundWorker. The problem is that when I try to update property (which calls NotifyPropertyChanged in setter) in RunWorkerCompleted event handler I get InvalidOperationException - The calling thread cannot access this object because a different thread owns it.

This MSDN article says that BackgroundWorker handles thread synchronization itself so I shouldn't care about using Dispatcher. But I see that it doesn't handle NotifyPropertyChanged correctly.

Can anybody help me with this issue?

EDIT

Here is my code (sorry for some irrelevant features):

backgroundWorker.DoWork += delegate(object sender, DoWorkEventArgs args)
                                           {
                                               var action = (Func<Bitmap>) args.Argument;
                                               args.Result = BitmapUtil.BitmapSourceFromBitmap(action());
                                           };

backgroundWorker.RunWorkerCompleted += delegate(object sender, RunWorkerCompletedEventArgs args)
                                                       {
                                                           if (args.Cancelled || (args.Error != null))
                                                           {
                                                               return;
                                                           }

                                                           ImageProcessed = (BitmapSource) args.Result;
                                                       };

...

public BitmapSource ImageProcessed
        {
            get { return imageProcessed; }

            set
            {
                imageProcessed = value;
                OnPropertyChanged(VMUtil.GetNameOf<ImageAnalyzerViewModel>(vm => vm.ImageProcessed));
            }
        }

Upvotes: 1

Views: 371

Answers (2)

user761172
user761172

Reputation: 69

This seems to be a matter of cross-thread issue try this:

public BitmapSource ImageProcessed         
{             
    get
    { 
        return imageProcessed; 
    }              
    set         
    {                 
         imageProcessed = value;   
         // bring the following to the main thread
         Deployment.Current.Dispatcher.BeginInvoke(() =>
         {
            OnPropertyChanged(VMUtil.GetNameOf<ImageAnalyzerViewModel>(vm => vm.ImageProcessed));   
          }); 

  }         
} 

Upvotes: 0

Robert Rossney
Robert Rossney

Reputation: 96702

The problem's not being caused by any code in RunWorkerCompleted. That code runs on the same thread that created the BackgroundWorker. The problem's in the method that's actually being run in the background.

Hard to say what that problem might be without seeing that code. The fact that you're silently discarding any errors that the method throws, instead of logging or reporting what's in args.Error, may enter into the problem too.

Upvotes: 1

Related Questions