Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 进度条没有进展_C#_Multithreading_Progress Bar - Fatal编程技术网

C# 进度条没有进展

C# 进度条没有进展,c#,multithreading,progress-bar,C#,Multithreading,Progress Bar,我有一个程序正在更新sqlserver中的一个表,我有一个表单,我想显示这个表的进度,进度条在增加,但没有显示。我需要使用后台工作人员来完成此操作吗?我在做什么的例子 public void updateTable(string tableName) { // con is an instance of my form to access progressbar con.progressBar1.Minimum = 1; con.progressBar1.Step = 1; st

我有一个程序正在更新sqlserver中的一个表,我有一个表单,我想显示这个表的进度,进度条在增加,但没有显示。我需要使用后台工作人员来完成此操作吗?我在做什么的例子

public void updateTable(string tableName)
{
  // con is an instance of my form to access progressbar
  con.progressBar1.Minimum = 1;
  con.progressBar1.Step = 1;
  string dbQuery = "select summet from someting"

  con.progressBar1.Maximum = address.Tables[0].Rows.Count;
  MessageBox.Show("progress bar max " + con.progressBar1.Maximum);

   foreach (DataRow LonLat in address.Tables[0].Rows)
   {
       con.progressBar1.PerformStep();
       MessageBox.Show(con.progressBar1.Value.ToString()); // this is incrementing
       //plus updating table 

   }


}

简短回答,是的。如果从主线程执行此操作,则不会看到进度条更新

长答案:

每当您修改用户界面时,从一段代码(该代码已翻译为“消息”)到窗口消息队列中,窗口消息队列将获取该消息并在主线程中相应地更新UI

但是,由于主线程忙于处理您的代码,因此它没有“时间”来实际更新用户界面,并且只有当您的过程完成后,才可以自由地更新用户界面。这就是为什么您会看到进度条从0%变为100%,而没有任何中间步骤

你应该做什么:


你想做的是把工作放到后台工作程序中,这样主线程就可以自由地处理UI更新请求。。。顺便说一句,如果你想保持UI的响应性,这是一种标准做法。

是的,你应该使用后台工作程序,但是它可能没有帮助,我们需要查看绑定和其他所有内容,要使用后台工作程序,请使用以下内容:

Window.Dispatcher.BeginInvoke((Action)(() =>
        {
            con.progressBar1.PerformStep();
        }

是的,你必须使用后台工作人员

BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += (o, ea) =>
    {
     // your code goes here
       }
 worker.RunWorkerCompleted += (q, ea) =>
    {
      }
 worker.RunWorkerAsync();

如果我们不能使用后台工作人员,就会发生这种情况。我有一个带有进度条的表单,它唯一的任务是从打开它的其他表单接受执行步骤的命令,而表单必须简单地执行此操作。这两种形式都在GUI线程中。 然而,我并没有从progressbar获得一致的行为。在下面的代码中,progressbar始终比其Value属性所表示的内容落后一步:

public partial class Form1 : Form
   {
      private readonly int m_numOfSteps;

      public Form1(int numOfSteps)
      {
         m_numOfSteps = numOfSteps;
         InitializeComponent();
      }

      private void Form1_Load( object sender, EventArgs e )
      {
         progressBar1.Step = (int)Math.Ceiling( 100.0 / m_numOfSteps );
      }

      public void DoStep(string msg)
      {
         progressBar1.PerformStep();
         label1.Text = msg;
         label2.Text = String.Format( "{0}%", progressBar1.Value  );
         label1.Refresh();
         label2.Refresh();
      }
   }

   public partial class Form2 : Form
   {
      public Form2()
      {
         InitializeComponent();
      }

      private void button1_Click( object sender, EventArgs e )
      {
         using( Form1 f = new Form1( 3 ) )
         {
            f.Show();
            f.Refresh();
            Thread.Sleep( 1000 );
            f.DoStep( "AAAA" );
            Thread.Sleep( 1000 );
            f.DoStep( "BBBB" );
            Thread.Sleep( 1000 );
            f.DoStep( "CCCC" );
            Thread.Sleep( 1000 );
         }
      }
   }

请注意,窗口是指位于的窗口进度条!所以我猜它的con.Dispatcher…BackgroundWorker对更新进度条有特定的支持;您只需要调用updateprogress方法,然后将事件处理程序附加到相应的事件。如果你这样做了,就不需要封送到UI线程。科尔多瓦,很好的解释,如果有一个示例代码,用一个新的线程和主线程更新UI元素来转移操作,那就太好了。