【问题标题】:Progress Bar and Threads进度条和线程
【发布时间】:2013-05-16 15:02:42
【问题描述】:

我有这个进度条类(测试线程)

public class ProgressBarUpdate
    {
        //Add getters and setters
        static MainGUI theForm = (MainGUI)Application.OpenForms[0];
        ProgressBar pBarCur = theForm.pBarCur; //Yes, accessing public for now
        bool updateCur = false;
        bool stopCur = false;
        bool showMax = false;
    public ProgressBarUpdate()
    {

    }
    public void resetCur()
    {
        pBarCur.Value = 0;
    }
    public void DoCurUpdate()
    {
        while (!stopCur)
        {
            if (pBarCur.Value < (pBarCur.Maximum / 10) * 9)
                pBarCur.PerformStep();
            if (showMax)
            {
                pBarCur.Value = pBarCur.Maximum;
                showMax = false;
            }
        }

    }
public void StopCur()
        {
            stopCur = true;
        }
        public void UpdateCur()
        {
            updateCur = true;
        }
        public void UpdateToMax()
        {
            showMax = true;
        }

然后我在不同的 A 类中调用所有这些以从那里更新 GUI:

ProgressBarUpdate updateBar = new ProgressBarUpdate();

        Thread currentProgressUpdater = new Thread(new ThreadStart(updateBar.DoCurUpdate));

        try
        {
            currentProgressUpdater.Start();

            currentProgressUpdater.Join();
        }
        catch (Exception)
        {

        }

在我运行它之后,我会看到我的应用程序停止响应的对话框(立即),然后它要求我关闭。我没有正确实现线程吗?还是我错过了一步?

【问题讨论】:

  • 如果您不想使用 BackgroundWorker(),请让您的 ProgressBarUpdate() 类引发自定义 events 以传递进度。主窗体会在创建 ProgressBarUpdate() 实例时订阅这些事件,然后在这些事件到来时根据接收到的信息更新其控件。确保正确使用委托和 Invoke() 来更新 GUI 以避免跨线程异常。

标签: c# multithreading progress-bar


【解决方案1】:

您的问题是对currentProgressUpdater.Join(); 的调用。你阻塞了 UI 线程。

创建新线程的全部意义在于允许 UI 线程继续处理 UI 事件。你不会让它那样做。启动一个线程然后立即加入它与直接执行代码并没有什么不同。

您还可以从新线程中运行的方法访问控件。那是行不通的。 UI 控件只能从 UI 线程访问。

【讨论】:

  • 有没有办法进行“智能”进度条更新?就像从另一个具有 for 循环的方法内部调用 update 方法并在每次迭代后更新?
  • @Alexey 不清楚你想要什么。您可以使用BackgroundWorker 来表示长时间运行的操作,并且它内置了对进度更新的支持,当您想要使用当前进度更新 UI 时,您可以使用它来触发事件。有关示例,请参阅 BackgroundWorker 的 MSDN 页面。
  • 或者你建议把进度条放在一个弹出窗体中,这是一个新线程,然后将值从主窗体传递到这个新窗体以更新进度条。这样进度条组件就不会被锁定。
  • @Alexey 我强烈不鼓励您使用多个 UI 线程。这将是一场噩梦;不要这样做。正确管理要困难得多,而不是容易。
  • 我要制作两个进度条,一个用于中间过程,一个用于总过程。中间是1个for循环,total是整个执行操作。我想为每个用户显示一个进度条并提供一个取消按钮,因此在每次中间操作之后,它都会检查是否取消被击中,并停止执行。我坚持让进度条与主进程一起运行。 (尝试在一个线程中全部完成,并被 Jon Skeet 嘲笑,所以我认为我做错了)。
【解决方案2】:

你在这里处于无限循环while (!stopCur)

您永远不会将stopCur 设置为true

【讨论】:

  • 该代码不在 UI 线程中,因此不会导致 UI 阻塞。
  • @Servy UI 线程正在等待它,所以正如您在回答中所说,这在这里并没有真正的区别
猜你喜欢
  • 2011-06-21
  • 1970-01-01
  • 2014-01-06
  • 2020-10-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多