在线程上显示Busy Indicator并启动应用程序:线程错误(调用线程无法访问此对象)

时间:2013-06-25 12:53:34

标签: c# .net wpf

我正在开发一个WPF应用程序并遵循MVVM方法。当用户点击“Enter”按钮时,我必须在登录屏幕上显示忙碌指示符。在“Enter”按钮上,我有一个名为“EnterCommand”的ICommand,然后检查身份验证,然后加载MainWindow。

private ICommand _EnterCommand;
public ICommand EnterCommand
{
    get
    {
        return _EnterCommand ?? (_EnterCommand = new DelegateCommand(() =>
        {
            Thread objThread = new Thread(LoadApplication);
            objThread.SetApartmentState(ApartmentState.STA);
            objThread.Start();

        }));
    }
}

IsBusy属于这个showprogress

private bool _ShowProgress = false;
public bool ShowProgress
{
    get { return _ShowProgress; }
    set
    {
        if (_ShowProgress != value)
        {
            _ShowProgress = value;
            FirePropertyChanged("ShowProgress");
        }
    }
}

我正在使用此命令创建一个线程,然后从(bool Property name:ShowProgress)MVVM设置IsBusy属性。

LoadApplication中的

public void LoadApplication()
{
    ShowProgress= true;
    if (AuthenticateUser)
    {
        MainWindow objMainWindow = new MainWindow();
        objMainWindow.Show();
        Application.Current.MainWindow.Close();
    }
    ShowProgress= false;
}

objMainWindow.Show()抛出错误 - 调用线程无法访问此对象,因为另一个线程拥有它。

同样在App.xaml中,我将StartupUri设置为我的“登录”窗口。

只要用户点击“Enter”按钮,就可以显示忙碌指示,但在显示mainWindow时失败。

错误消息是“调用线程无法访问此对象,因为其他线程拥有它。”

只要我的MainWindow(主屏幕)没有启动,我就必须显示busyindicator。

有任何帮助来纠正这个问题吗?

2 个答案:

答案 0 :(得分:0)

抛出异常,因为您无法从后台线程访问UI元素。

你必须从主/ UI线程调用objMainWindow.Show()或要求调度员为你调用

如果你必须从backgorund线程调用它,你可以这样做:

Action act = () =>
{
   MainWindow objMainWindow = new MainWindow();
   objMainWindow.Show();
  Application.Current.MainWindow.Close();
};

 System.Windows.Application.Current.Dispatcher.Invoke(act);

我建议您阅读以下MSDN Article

答案 1 :(得分:-1)

试试这段代码:

private void AsyncCallback(IAsyncResult result){
    var dispatcher = Dispatcher.CurrentDispatcher;
    dispatcher.Invoke(new Action(() =>
    {
        MainWindow objMainWindow = new MainWindow();
        objMainWindow.Show();
        Application.Current.MainWindow.Close();
    }
}

修改

public void LoadApplication()
    {
        ShowProgress= true;
        if (AuthenticateUser)
        {
            var dispatcher = Dispatcher.CurrentDispatcher;
            dispatcher.Invoke(new Action(() =>
            {
                MainWindow objMainWindow = new MainWindow();
                objMainWindow.Show();
                Application.Current.MainWindow.Close();
            }
        }
        ShowProgress= false;
    }