如何从 BackgroundWorker.DoWork 事件中获取更新

How to get update from BackgroundWorker.DoWork Event

在我的登录 window 中,当我单击登录按钮时,将执行配置和登录过程,这些方法在另一个 class 文件中。到目前为止,我所取得的成就是当我单击登录按钮时,加载动画将显示在登录 window 之上,并且这些过程也将被执行。配置class文件中有一些登录错误检查,所以当登录错误被捕获时,会提示一个包含相关信息的消息框并停止登录过程,问题是消息框不会被提示,因为我将这些配置和登录过程放在 BackgroundWorker.DoWork 事件中。

这是 Login.xaml.cs 的代码:

 private void LoginBtn_Click(object sender, RoutedEventArgs e) 
 {
   Loading.Visibility = Visibility.Visible; //The loading animation

   Loading.Visibility = Visibility.Visible;
   Cursor = Cursors.Wait;

   bw.DoWork += new DoWorkEventHandler(LoginInfoVerification);
   bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
   bw.WorkerReportsProgress = true;
   bw.RunWorkerAsync();
 }

private void LoginInfoVerification(object sender, DoWorkEventArgs e) {
  var loginInfoVerification = config.ServerConnection(loginInfo.userName,
    loginInfo.galPassword, loginInfo.place,
    loginInfo.host, loginInfo.port,
    loginInfo.application);
}

private void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
  if (GlobalVariables.loginSuccess == true) 
  {
    //Pass these variables to main window
    var mainWindow = new MainWindow(loginInfo.userName, loginInfo.place, loginInfo.host, loginInfo.port,
                                    loginInfo.application);
    mainWindow.Show(); 

    this.Close();
  } 

  else
    Loading.Visibility = Visibility.Collapsed;

  Cursor = Cursors.Arrow;
}

对于Configuration.cs:

public Configuration ConfigServerConnection(string loginUserName, string loginPassword, string loginPlace, string loginHost, int loginPort, string loginApplication)
{
  //Server connection
  //Login info verification
  //If login error caught, prompt message box, different errors, different message
 }

对于我的情况,在同时处理UI更新和进程更新方面有什么更好的建议吗?请帮忙。

要显示消息框,您需要使用 Dispatcher.Invoke 切换回 UI 线程,请参阅 this

Application.Current.Dispatcher.Invoke(() => /* show appropriate message box */);

或者,如果您使用的是 .NET 4.5 或更高版本,您可以使用 async-await 通过使用 async 关键字标记 LoginBtn_Click 然后等待登录,让您的生活变得更加轻松过程。

如果有 ServerConnection 的异步版本,那 returns 一个任务你可以 await 否则你可以使用 Task.Run() 来执行 ServerConnection在线程池线程上。

Await 将异步启动登录操作,完成后将恢复 GUI 线程上的其余方法,因此您可以在不使用 [=12= 的情况下操作 GUI 组件].

private async void LoginBtn_Click(object sender, RoutedEventArgs e) 
 {
   Loading.Visibility = Visibility.Visible; //The loading animation

   Loading.Visibility = Visibility.Visible;
   Cursor = Cursors.Wait;      

   LoginVerification loginInfoVerification = null;

   await Task.Run(() =>
                 {
                     loginInfoVerification = config.ServerConnection(loginInfo.userName, 
                                                                     loginInfo.galPassword, 
                                                                     loginInfo.place, 
                                                                     loginInfo.host, 
                                                                     loginInfo.port, 
                                                                     loginInfo.application);
                 });   

      .. rest of code, check login success, show message box..
 }