【问题标题】:run the progress bar in another thread在另一个线程中运行进度条
【发布时间】:2013-03-07 09:06:19
【问题描述】:

我试图在单击按钮时显示进度条,并在工作完成时隐藏它。但是当我在按钮事件处理程序中显示进度条时,它不起作用,只有在工作完成后才会显示。

这是我的代码:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    this.Dispatcher.BeginInvoke((Action)(() =>
        {
            loadingprgoress.Visibility = Visibility.Visible;
        }));

    int usresult, psresult;

    con.Open();

    SqlDataReader data = null;
    String myQueryEdit1 = @"SELECT Username, Password FROM [dbo].[Table]";
    com.CommandText = myQueryEdit1;
    com.Connection = con;
    data = com.ExecuteReader();
    Random rnd = new Random();
    int newrnd = rnd.Next(1, 100);

    if (data.Read())
    {

        string userhash = GenerateHashWithSalt(data["Username"].ToString(), newrnd.ToString());
        string passhash = GenerateHashWithSalt(data["Password"].ToString(), newrnd.ToString());
        string userhash1 = GenerateHashWithSalt("admin", newrnd.ToString());
        string passhash1 = GenerateHashWithSalt(pasbox.Password, newrnd.ToString());

        usresult = userhash.CompareTo(userhash1);
        psresult = passhash.ToString().CompareTo(passhash1);
        if (usresult == 0 && psresult == 0)
        {
            con.Close();
            dental_main_Window neww = new dental_main_Window();
            neww.Show();
            Close();
        }
        else
        {
            con.Close();
            pasbox.Password = "";
        }

        Thread.Sleep(3000);

        this.Dispatcher.BeginInvoke((Action)(() =>
           {
               loadingprgoress.Visibility = Visibility.Hidden;
           }));
        return;
    }
}

【问题讨论】:

    标签: c#


    【解决方案1】:

    发生这种情况是因为您的 UI 线程正在完成所有工作(访问数据库),并且在完成之前,它无法处理更多消息(例如显示进度条)。

    您需要做相反的事情,在没有 BeginInvoke 的 UI 线程中显示进度条,并在另一个线程中进行数据库访问。当您其他线程完成时,您需要在 UI 线程上执行 BeginInvoke 以隐藏进度条。

    这是另一个重要的注意事项:this.Dispatcher.BeginInvoke 不会产生线程。它将命令“推送”到 UI 线程的队列,因为所有 UI 操作都必须从 UI 线程执行。

    这是你要做的:

    private void Button_Click_1(object sender, RoutedEventArgs e)

    1. 显示进度条
    2. 使用任务启动后台进程
    3. 在您的第一个任务中添加一个延续任务,将消息发送到流程已完成的 UI
    4. 在延续任务中使用 this.Dispatcher.BeginInvoke 以便 UI 工作人员发生在 UI 线程上。

    【讨论】:

      【解决方案2】:

      看看后台工作人员 (http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx)

      它允许您在单独的专用线程上运行操作。 在后台计算期间,您可以引发 ProgressChanged 事件来通知 UI 并相应地更新 ProgressBar:

      private BackgroundWorker _worker;
      
      public Form1(string[] args)
      {
          InitializeComponent();
      
      
          _worker = new BackgroundWorker();
          _worker.WorkerReportsProgress = true;
      
          _worker.RunWorkerCompleted += worker_WorkCompleted;
          _worker.DoWork += worker_DoWork;
          _worker.ProgressChanged += worker_ProgressChanged;
      
      
      }
      
      private void worker_DoWork(object sender, DoWorkEventArgs e)
      {
          DoStuff();
      }
      private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
      {
          progressBar1.Value = e.ProgressPercentage;
      }
      private void worker_WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
      {
          _running = false;
          UpdateUi();
      }
      
      private bool DoStuff()
      {
              //...
              _worker.ReportProgress(20);
              //...
              _worker.ReportProgress(20);
      
              return true;
      
      }
      
      private void btnUpdate_Click(object sender, EventArgs e)
      {
          _worker.RunWorkerAsync();
      }
      

      【讨论】:

        【解决方案3】:

        WPF 中的 UI 需要在 UI 线程上执行。你也意识到了这一点,因为我可以看到你使用 Dispatcher.BeginInvoke 与你的进度窗口进行交互。

        不过,您的问题是您也在 UI 线程上执行长时间运行的任务。当你这样做时,你不会给进度窗口一个操作的机会。该线程被长时间运行的任务消耗,因此无法为 UI 提供服务。

        解决方案是远离 UI 线程执行长时间运行的任务。

        【讨论】:

        • 当我这样做时,它会出错,该对象是当前线程自己的,不能被另一个线程访问。\
        • 那么你需要解决这个问题。它不会改变您需要远离 UI 线程执行长时间运行的任务这一事实。
        猜你喜欢
        • 1970-01-01
        • 2010-12-16
        • 1970-01-01
        • 1970-01-01
        • 2011-08-12
        • 1970-01-01
        • 2012-08-19
        • 2016-09-07
        相关资源
        最近更新 更多