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

本文关键字:线程 调用 对象 错误 访问 应用程序 显示 指示器 启动 | 更新日期: 2023-09-27 18:19:45

我正在开发一个WPF应用程序,并遵循MVVM方法。当用户点击"输入"按钮时,我必须在登录屏幕上显示忙碌指示灯。在"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属性名称: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设置为我的"登录"窗口。

当用户单击"输入"按钮时,它可以显示忙碌指示器,但在显示主窗口时失败。

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

只要我的主窗口(主屏幕)没有启动,我就必须显示忙碌指示器。

有什么可以纠正的吗?

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

由于无法从后台线程访问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文章

试试这个代码:

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