Search code examples
mvvmwindows-phone-7.1silverlight-toolkitmultithreading

PerformanceProgressBar "Invalid cross-thread access" exception


I am developing WP7 app. I met some unexpected behavior. I use PerformanceProgressBar from the SilverLight toolktit in my app in several pages. These PerformanceProgressBars are binded to ViewModel property called IsBusy. Each page has its own ViewModel.

....<toolkit:PerformanceProgressBar VerticalAlignment="Top" HorizontalAlignment="Left" IsIndeterminate="{Binding IsBusy}" Visibility="{Binding IsBusy, Converter={StaticResource BoolToVisibilityConverter}}"
/>......

    public bool IsBusy
    {
        get
        {
            return this._isBusy;
        }
        set
        {
            if (value == this._isBusy)
            {
                return;
            }

            this._isBusy = value;
            RaisePropertyChanged("IsBusy");
        }
    }

When I change IsBusy value, I get "Invalid cross-thread access" exception.

Any ideas?


Solution

  • Any change to the visual-tree, i.e. the UI of your application, must be performed from the UI thread. This includes changes to properties that occur via bindings. My guess is that you are updating this property via a background-thread?

    In this case, you need to marshal the property change onto the UI thread via the Dispatcher.

    public bool IsBusy
    {
        get
        {
            return this._isBusy;
        }
        set
        {
            if (value == this._isBusy)
            {
                return;
            }
    
            Application.Current.Dispatcher.BeginInvoke(() => {
              this._isBusy = value;
              RaisePropertyChanged("IsBusy");
            });
        }
    }
    

    This exposes the view to your view-model, so is not very good MVVM! In this case I would 'hide' the dispatcher behind a single method interface IMarshalInvoke, that you provide to the ViewModel.

    Or consider using BackgroundWorker which can fire ProgressChanged events onto the UI thread for you.