简体   繁体   English

C#进度条不合作

[英]C# Progress Bar not cooperating

I've run into a really weird situation. 我遇到了一个非常奇怪的情况。 This should be so simple, yet I'm not sure why it's happening. 这应该是如此简单,但我不确定为什么会这样。

I have a marquee progress bar set to visible=false as it's initial state. 我将一个选取框进度条设置为visible = false,因为它是初始状态。 Then at one point during runtime I call one of my functions and right before calling it I set the PB to visible=true and after the function ends, I set it back to visible=false. 然后在运行期间的某个时刻,我调用我的一个函数,然后在调用它之前将PB设置为visible = true,在函数结束后,我将其设置为visible = false。 It doesn't get any simpler then this. 它没有变得更简单。

If (something)
{
  pb.visible=true;
  runMyfunction(x, x, x, x,);
  pb.visible=false;
}

The problem is that I never see the PB. 问题是我从未见过PB。 If I comment out my function and remove =false, the PB shows up, but as soon as I get my function back in there, PB never shows up. 如果我注释掉我的函数并删除= false,则会显示PB,但只要我恢复了我的功能,PB就不会出现。

I've tried various approaches. 我尝试了各种方法。 Using If statements to make sure I get a progress bar before it ever touches the function and it still keeps the PB hidden. 使用If语句确保我在触摸函数之前得到一个进度条,它仍然保持PB隐藏。

Am I missing something? 我错过了什么吗? This does not seem like it should be so complicated. 这似乎不应该是如此复杂。 Show object, run function, hide object. 显示对象,运行函数,隐藏对象。 Right? 对? :) :)

This is because your function is tieing up the UI thread. 这是因为您的功能正在占用UI线程。 Setting the ProgressBar to visible requires the UI thread to be freed up to draw it, but instead you continue to process your function which never gives it time to draw. 将ProgressBar设置为可见需要释放UI线程以绘制它,而是继续处理您的函数,从而没有时间绘制。

You can sort of work around this by calling: Application.DoEvents Which stops processing your method long enough to process some windows messages (and do the related drawing). 您可以通过调用以下方法解决此问题: Application.DoEvents停止处理您的方法足够长的时间来处理一些Windows消息(并执行相关的绘图)。

The big problem with Application.DoEvents is that assuming you're updating your Progress Bar from your runMyfunction() you're going to have to constantly call Application.DoEvents to allow your PB to draw, or you'll see it, but you'll never see it update. Application.DoEvents的一个大问题是假设你从runMyfunction()更新你的进度条,你将不得不经常调用Application.DoEvents来允许你的PB绘制,或者你会看到它,但你永远不会看到它更新。

A better solution is to push your runMyfunction() call to a background thread and update the progress bar asynchronously from there. 更好的解决方案是将runMyfunction()调用推runMyfunction()后台线程,并从那里异步更新进度条。 That, of course is a lot more complicated, but makes for a better user experience. 当然,这更复杂,但可以带来更好的用户体验。

My guess is myRunFunction() runs on the UI Thread. 我的猜测是myRunFunction()在UI线程上运行。

Try running it inside a BackgroundWorker and start the ProgressBar before calling RunWorkerAsync and stop it in the RunWorkerCompleted event. 尝试在BackgroundWorker中运行它并在调用RunWorkerAsync之前启动ProgressBar并在RunWorkerCompleted事件中将其停止。

Edited with code example: 用代码示例编辑:

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;
    }
}

inside of your runMyFunction() method call Application.DoEvents() to force your app to redraw and process the windows message loop: runMyFunction()方法内部调用Application.DoEvents()来强制你的应用重绘并处理windows消息循环:

eg 例如

void myRunFunction()
{
  while (someFlag)
  {
   // do work
   pb.Value = someValue;
   Application.DoEvents();
  }
}

It could be that your function is running and completing too fast for you to see the bar. 可能是您的功能正在运行并且完成得太快,您无法查看该栏。 I know that I've had this happen a few times before. 我知道我之前已经发生了几次这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM