C# 进度条和线程

C# 进度条和线程,c#,multithreading,progress-bar,C#,Multithreading,Progress Bar,我有这个进度条类(测试线程) 在我运行它之后,我得到一个对话框,我的应用程序已经停止响应(马上),然后它要求我关闭。我没有正确地实现线程吗?还是我遗漏了一个步骤?你在这里处于无限循环,而(!stopCur) 您从未将stopCur设置为true您的问题是调用currentProgressUpdater.Join()。您正在阻止UI线程 创建新线程的全部目的是允许UI线程继续处理UI事件。你不能让它那样做。启动一个线程,然后立即加入它,这与直接执行代码并没有什么不同 您还可以从新线程中运行的方法访

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


在我运行它之后,我得到一个对话框,我的应用程序已经停止响应(马上),然后它要求我关闭。我没有正确地实现线程吗?还是我遗漏了一个步骤?

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


您从未将
stopCur
设置为
true

您的问题是调用
currentProgressUpdater.Join()。您正在阻止UI线程

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


您还可以从新线程中运行的方法访问控件。那不行。用户界面控件只能从用户界面线程访问。

该代码不在用户界面线程中,因此不会导致用户界面阻塞。@请注意,用户界面线程正在等待它,因此正如您在回答中所说,这并没有真正的区别。有没有办法更新“智能”进度条?就像从另一个方法内部调用update方法,该方法具有for循环,并在每次迭代后更新?@Alexey不清楚您想要什么。您可以使用
BackgroundWorker
来表示长时间运行的操作,并且它内置了对进度更新的支持,当您希望使用当前进度更新UI时,可以使用该支持来触发事件。请参阅BackgroundWorker的MSDN页面以获取示例。或者您是否建议将进度条放在一个弹出窗体中,这是一个新线程,然后将主窗体中的值传递到此新窗体以更新进度条。这样进度条组件就不会被锁定。@Alexey我强烈建议您不要使用多个UI线程。这将是一场噩梦;不要这样做。要正确地管理它要困难得多,而不是更容易。我想制作两个进度条,一个用于中间过程,一个用于整个过程。对于循环,中间值为1,总计为整个执行操作。我想向用户显示每个操作的进度条,并提供一个cancel按钮,这样在每个中间操作之后,它都会检查是否点击了cancel,并停止执行。我一直坚持让进度条与主进程同时运行。(尝试在一个线程中全部完成,但遭到Jon Skeet的嘲笑,所以我认为我做得不对)。如果不想使用BackgroundWorker(),请让ProgressBarUpdate()类引发自定义
事件
以传递进度。主窗体将在创建ProgressBarUpdate()实例时订阅这些事件,然后在这些事件发生时根据收到的信息更新其控件。确保正确使用委托和Invoke()来更新GUI,以避免跨线程异常。
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;
        }
ProgressBarUpdate updateBar = new ProgressBarUpdate();

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

        try
        {
            currentProgressUpdater.Start();

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

        }