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

时间:2015-08-02 10:16:58

标签: c# wpf backgroundworker

在我的登录窗口中,当我单击登录按钮时,将执行配置和登录过程,并且这些方法位于另一个类文件中。到目前为止,我所取得的成就是当我点击登录按钮时,加载动画将显示在登录窗口的顶部,并且这些过程也将被执行。在配置类文件中有一些登录错误检查,所以当抓到登录错误时,将提示一个带有相关信息的消息框并停止登录过程,问题是因为我放了那些配置后消息框不会被提示出来和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更新和流程更新?请帮忙。

1 个答案:

答案 0 :(得分:1)

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

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

或者,如果您使用的是.NET 4.5或更高版本,则可以使用async-await标记LoginBtn_Click并使用async关键字等待登录过程,从而使您的生活更轻松。

如果有ServerConnection的异步版本返回任务,您只能await,否则您可以使用Task.Run()在线程池线程上执行ServerConnection

Await将异步启动登录操作,一旦完成,将在GUI线程上恢复该方法的其余部分,这样您就可以在不使用Dispatcher.Invoke的情况下操作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..
 }