PerformanceProgressBar“无效的跨线程访问"例外 [英] PerformanceProgressBar "Invalid cross-thread access" exception

查看:93
本文介绍了PerformanceProgressBar“无效的跨线程访问"例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发WP7应用程序.我遇到了一些意外的行为.我在几页的应用程序中使用SilverLight工具中的PerformanceProgressBar.这些PerformanceProgressBars绑定到名为IsBusy的ViewModel属性.每个页面都有自己的ViewModel.

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}}"
/>......

....<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");
        }
    }

更改IsBusy值时,出现无效的跨线程访问"异常.

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

有什么想法吗?

推荐答案

对可视树的任何更改,即应用程序的UI,都必须从UI线程执行.这包括通过绑定发生的属性更改.我的猜测是您要通过后台线程更新此属性吗?

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?

在这种情况下,您需要通过Dispatcher将属性更改编组到UI线程上.

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");
        });
    }
}

这会将视图公开给您的视图模型,因此不是很好的MVVM!在这种情况下,我将隐藏"调度程序隐藏在您提供给ViewModel的单个方法接口IMarshalInvoke后面.

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.

或者考虑使用BackgroundWorker,它可以为您在UI线程上触发ProgressChanged事件.

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

这篇关于PerformanceProgressBar“无效的跨线程访问"例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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