ProgressBar的运行速度比定义的快

时间:2013-04-20 15:08:19

标签: c# winforms

我的应用程序运行文件,每个文件都有自己的运行时间。 此函数以毫秒为单位获取进度时间应运行的时间:

timerProgress = my timer
pbStatus = my progress bar

public void AnimateProgBar(int milliSeconds)
{
    if (!timerProgress.Enabled && milliSeconds != 0)
    {
        pbStatus.Value = 0;;
        timerProgress.Interval = milliSeconds / 100;
        timerProgress.Enabled = true;
    }
}

这是我的计时器,用于填充进度条:

   private void timerProgress_Tick(object sender, EventArgs e)
    {
        if (pbStatus.Value < 100)
        {
            pbStatus.Value += 1;
            pbStatus.Refresh();
        }
        else
        {
            timerProgress.Enabled = false;
        }
    }

我的问题是进度条运行得太快,例如,如果AnimateProgBar获得12000(12秒)的值,则进度条仅运行6-7秒。

3 个答案:

答案 0 :(得分:3)

你的代码不起作用,这很可疑。我尝试了几次,每次错过大约0.6秒;似乎 计时器只是不精确

你可以做的是自己照顾时间而不是信任计时器:

WithEvents Tmr As New Timer With {.Interval = 100}
Dim startTime As Date, AnimationTime%

Sub AnimateProgress(ms%)
    If ms <= 0 Then Exit Sub

    ProgressBar1.Value = 0
    AnimationTime = ms
    startTime = Now

    Tmr.Start()
End Sub

Private Sub Tmr_Tick() Handles Tmr.Tick
    ProgressBar1.Value = Math.Min((Now - startTime).TotalMilliseconds / AnimationTime, 1) * 100
    If ProgressBar1.Value = 100 Then Tmr.Stop()
End Sub

编辑 - 回复下面的回复:

哦对不起,不是它的vb.net。我也知道这两种语言,但我更喜欢vb,并且倾向于认为其他人也这样做。

这是c#版本:

DateTime startTime; int animationTime;

void AnimateProgress(int ms) {
    if (ms <= 0) return;

    progressBar1.Value = 0;
    animationTime = ms;
    startTime = DateTime.Now;

    Tmr.Start();
}

private void Tmr_Tick(object sender, EventArgs e) {
    progressBar1.Value = (int)(Math.Min((DateTime.Now - startTime).TotalMilliseconds / animationTime, 1) * 100);
    if (progressBar1.Value == 100) Tmr.Stop();
}

答案 1 :(得分:0)

您可以根据PerformStep method

尝试使用此示例
var progressBar = new System.Windows.Forms.ProgressBar();
progressBar.Maximum = 100;
progressBar.Minimum = 0;
progressBar.Step = 10;

//begin loop

//Your treatment of step 
progressBar.PerformStep();

//end loop

msdn link:http://msdn.microsoft.com/fr-fr/library/system.windows.forms.progressbar.performstep(v=vs.80).aspx

你有样品

private void CopyWithProgress(string[] filenames)
{
    // Display the ProgressBar control.
    pBar1.Visible = true;
    // Set Minimum to 1 to represent the first file being copied.
    pBar1.Minimum = 1;
    // Set Maximum to the total number of files to copy.
    pBar1.Maximum = filenames.Length;
    // Set the initial value of the ProgressBar.
    pBar1.Value = 1;
    // Set the Step property to a value of 1 to represent each file being copied.
    pBar1.Step = 1;

    // Loop through all files to copy.
    for (int x = 1; x <= filenames.Length; x++)
    {
        // Copy the file and increment the ProgressBar if successful.
        if(CopyFile(filenames[x-1]) == true)
        {
            // Perform the increment on the ProgressBar.
            pBar1.PerformStep();
        }
    }
}

link:http://msdn.microsoft.com/fr-fr/library/system.windows.forms.progressbar.performstep(v=vs.80).aspx

答案 2 :(得分:0)

我无法重现您的问题。我刚刚在你的问题中详细测试了一个带有ProgressBar和Timer的新表单,只添加了一个按钮来开始测试,还有一个标签显示已用时间:

    DateTime start;
    private void button1_Click(object sender, EventArgs e)
    {
        start = DateTime.Now;
        AnimateProgBar(12000);
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        label1.Text = DateTime.Now.Subtract(start).TotalSeconds.ToString();
        //the rest of your code, starting with "if (pbStatus.Value < 100)"

我一直有12.6秒,直到progressBar填满(并且计时器停止,冻结标签文本)......也许你的progressBar的一部分被隐藏了?

[编辑] 如果您对BlackCap注意到的额外0.6秒感到好奇,那是因为您将定时器间隔设置为120毫秒,但定时器事件的分辨率大约为18毫秒,因此它实际上将以126而不是120来触发。