运行耗时的任务+更新winform

时间:2014-01-15 17:53:28

标签: c# winforms parallel-processing task

我有以下情况:

  1. “对话框”窗口调用耗时的网络任务
  2. 等待任务结果
  3. 同时我想更新进度条或具有某种状态的文本框 - 所以我尝试了以下内容:

      • Backgroundworker - > BW中的进度条
      • UI THREAD中的网络任务
    1. -
      • 任务 - >网络功能
      • 后台工作人员 - >进度条
    2. 在这两种情况下,我的GUI都不会更新,直到获取任务结果。如果你能指出我正确的方向,我将非常感激。

      private void button1_Click ( object sender, EventArgs e )
      {
         bw.RunWorkerAsync(); // Updates a textbox
         Task<bool> test2 = new Task<bool>( () => _AuthHandler( sender, e, textBox1.Text, textBox2.Text ) );
         try
              {
                  test2.Start();
                  bool result = test2.Result;
                  //bool result = _AuthHandler.Invoke( sender, e, textBox1.Text, textBox2.Text );
                  if ( result )
                  {
      
                      //Do Somethin..
                  }
               }
          catch(Exception e) {
              //Do Something
          }
      }
      // -------BW TEST CODE --------//
          public void  smthn ()
          {
              textBox3.Text += ".";
          }
          void bw_DoWork ( object sender, DoWorkEventArgs e )
            {
                for(int i = 0;; i++) 
                {
                    bw.ReportProgress( i );
                    Thread.Sleep( 250 );
                }
             }
      
          bool result = false;
          void bw_RunWorkerCompleted ( object sender, RunWorkerCompletedEventArgs e )
          {
              MessageBox.Show( "Result Set" );
              result = (bool)e.Result;
          }
          void bw_ProgressChanged ( object sender, ProgressChangedEventArgs e )
          {
              if ( textBox3.InvokeRequired )
              {
                  this.Invoke( new Action( smthn ) );
              }
              else
              {
                  smthn();
              }
          }
      

3 个答案:

答案 0 :(得分:1)

您正在阻止UI线程,直到某些非UI工作完成。不要那样做。让UI线程做UI工作,安排在另一个线程中完成非UI工作,然后让它做什么都不做;它将回到处理其他UI事件。

BackgroundWorker专门用于让UI执行一些非UI工作,并使用进度或结果更新UI。让BGW的DoWork方法完成您的实际工作,更新更新的处理程序中的进度条,并在完成的处理程序中显示结果。 BGW将负责在UI线程中运行除DoWork事件之外的所有事件,因此您无需手动调用UI线程。

您的代码无法正常工作的原因是您通过等待任务来阻止UI线程,并且由于它被阻止,因此从BGW的进度事件安排的UI更新没有机会运行,直到整件事情结束了。

答案 1 :(得分:0)

您的网络任务应该使用DoWork()方法在后台线程中运行,根据需要调用ReportProgress()然后,在您的主UI线程中,订阅ProgressChanged事件,并且更新您的ProgressBar

答案 2 :(得分:0)

谢谢大家......我意识到我阻止了UI线程。所以我制作了一个通用课程,包括两个背景工作者,进度事件,酒吧和一个完成的事件 - &gt;它调用后处理功能。我想这是大多数人推荐的方法。

虽然有其他选择吗?那么async / await