【问题标题】:PerformanceProgressBar "Invalid cross-thread access" exceptionPerformanceProgressBar“无效的跨线程访问”异常
【发布时间】:2012-01-20 06:22:58
【问题描述】:

我正在开发 WP7 应用程序。我遇到了一些意想不到的行为。我在我的应用程序的几个页面中使用 SilverLight 工具包中的 PerformanceProgressBar。这些 PerformanceProgressBar 绑定到名为 IsBusy 的 ViewModel 属性。每个页面都有自己的 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");
        }
    }

当我更改 IsBusy 值时,我得到“无效的跨线程访问”异常。

有什么想法吗?

【问题讨论】:

    标签: mvvm windows-phone-7.1 silverlight-toolkit multithreading


    【解决方案1】:

    对可视化树(即应用程序的 UI)的任何更改都必须从 UI 线程执行。这包括通过绑定对属性进行的更改。我的猜测是您正在通过后台线程更新此属性?

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

    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 后面。

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

    【讨论】:

    • 你的猜测是正确的。我正在调用异步 Web 服务方法,其中 IsBusy 属性在结果 CallBack 中更改为 false。你能解释一下你对 IMarshaledInvoke 的建议吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-04
    相关资源
    最近更新 更多