C#进度条不配合

C#进度条不配合,c#,progress-bar,C#,Progress Bar,我遇到了一个非常奇怪的情况。这应该很简单,但我不知道为什么会发生 我有一个字幕进度条设置为visible=false,因为它是初始状态。然后在运行时的某个时刻,我调用了我的一个函数,在调用它之前,我将PB设置为visible=true,在函数结束后,我将其设置回visible=false。再简单不过了 If (something) { pb.visible=true; runMyfunction(x, x, x, x,); pb.visible=false; } 问题是我从来没有见

我遇到了一个非常奇怪的情况。这应该很简单,但我不知道为什么会发生

我有一个字幕进度条设置为visible=false,因为它是初始状态。然后在运行时的某个时刻,我调用了我的一个函数,在调用它之前,我将PB设置为visible=true,在函数结束后,我将其设置回visible=false。再简单不过了

If (something)
{
  pb.visible=true;
  runMyfunction(x, x, x, x,);
  pb.visible=false;
}
问题是我从来没有见过PB。如果我注释掉我的函数并remove=false,PB就会出现,但一旦我把函数放回那里,PB就再也不会出现

我尝试过各种方法。使用If语句确保在它接触函数之前获得一个进度条,并且它仍然隐藏PB


我错过什么了吗?这似乎不应该如此复杂。显示对象、运行函数、隐藏对象。对吧?:)

runMyFunction()
方法调用
Application.DoEvents()
中强制应用程序重新绘制并处理windows消息循环:

e、 g


这可能是因为您的函数正在运行,并且完成得太快,以至于您无法看到条形图。我知道这种情况以前发生过几次。

这是因为您的函数正在绑定UI线程。将ProgressBar设置为visible需要释放UI线程来绘制它,但是您需要继续处理函数,这永远不会给它绘制时间

您可以通过调用:来解决这一问题,它将停止处理您的方法足够长的时间,以处理一些windows消息(并进行相关绘图)

Application.DoEvents
的一个大问题是,假设您正在从
runMyfunction()
更新进度条,则必须不断调用
Application.DoEvents
以允许PB绘制,否则您将看到它,但您永远看不到它的更新


更好的解决方案是将
runMyfunction()
调用推送到后台线程,并从那里异步更新进度条。这当然要复杂得多,但有助于获得更好的用户体验。

我的猜测是
myRunFunction()
在UI线程上运行

在调用
RunWorkerAsync
并在
RunWorkerCompleted
事件中停止它之前,请尝试在内部运行它并启动ProgressBar

编辑代码示例:

public class SomeClass
{
    private BackgroundWorker _myFunctionBackgroundWorker;
    private SomeProgressBar pb;

    public SomeClass()
    {
        _myFunctionBackgroundWorker = new BackgroundWorker();
        _myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork;
        _myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted;

        pb.visible = true;
        _myFunctionBackgroundWorker.RunWorkerAsync();
    }

    private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        runMyfunction();
    }


    private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        pb.visible = false;
    }
}

这是winforms或asp.net或WPF还是什么?您指的是asp.net的winforms进度条吗?BackgroundWorker可能非常适合这种情况。它封装了许多您需要的方法。这非常好,因为它确实解决了问题。但是,由于在函数运行约10秒时,我的应用程序仍然被占用,因此字幕从不移动。我只是做了一个简单的路由,在函数运行时显示字幕,然后在最后删除它。我要用backgroundworker试试ROBOlav的建议。效果很好!非常感谢。但有一个问题。我的函数有几个catch语句,当它遇到这些语句时,我会得到一个跨线程错误。我想出于某种原因,这些都没有封装在后台工作人员启动的原始线程中。我能修好吗?没关系,我知道了。我不得不重新安排我的函数,但一旦我把我所有的结果都交给e.Result,一切都很完美!再次感谢您使用backgroundworker为我提供了正确的设置方法。
public class SomeClass
{
    private BackgroundWorker _myFunctionBackgroundWorker;
    private SomeProgressBar pb;

    public SomeClass()
    {
        _myFunctionBackgroundWorker = new BackgroundWorker();
        _myFunctionBackgroundWorker.DoWork += myFunctionBackgroundWorker_DoWork;
        _myFunctionBackgroundWorker.RunWorkerCompleted += myFunctionBackgroundWorker_RunWorkerCompleted;

        pb.visible = true;
        _myFunctionBackgroundWorker.RunWorkerAsync();
    }

    private void myFunctionBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        runMyfunction();
    }


    private void myFunctionBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        pb.visible = false;
    }
}