c#进度条滞后问题。

楚楚3107 2017-08-30 02:26:16

问题描述:
点击开始时:label中的数据已开始走到10%左右,进度条才从0开始走。
等到label处理完毕时,进度条还没有到头,这样很明显显得很假。一个快,一个慢。以下是代码,求大神帮忙看下:
/// <summary>
/// 后台线程
/// </summary>
private BackgroundWorker bkWorker = new BackgroundWorker();

/// <summary>
/// 步进值
/// </summary>
private int percentValue = 0;

public Form1()
{
InitializeComponent();

bkWorker.WorkerReportsProgress = true;
bkWorker.WorkerSupportsCancellation = true;
bkWorker.DoWork += new DoWorkEventHandler(DoWork);
bkWorker.ProgressChanged += new ProgressChangedEventHandler(ProgessChanged);
bkWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(CompleteWork);
}

public void DoWork(object sender, DoWorkEventArgs e)
{
// 事件处理,指定处理函数
e.Result = ProcessProgress(bkWorker, e);
}

public void ProgessChanged(object sender, ProgressChangedEventArgs e)
{
// bkWorker.ReportProgress 会调用到这里,此处可以进行自定义报告方式
this.progressBar1.Value = e.ProgressPercentage;//进度条的值/步进
int percent = (int)(e.ProgressPercentage / percentValue);
this.label1.Text = "处理进度:" + Convert.ToString(percent) + "%";
}

public void CompleteWork(object sender, RunWorkerCompletedEventArgs e)
{
this.label1.Text = "处理完毕!";
}

private int ProcessProgress(object sender, DoWorkEventArgs e)
{
for (int i = 0; i <= 100; i++)
{
if (bkWorker.CancellationPending)
{
e.Cancel = true;
return -1;
}
else
{
// 状态报告
bkWorker.ReportProgress(i);
// 等待,用于UI刷新界面,很重要
System.Threading.Thread.Sleep(100);

}
}

return -1;
}

private void button1_Click(object sender, EventArgs e)
{
percentValue = 1;
this.progressBar1.Maximum = 100;
// 执行后台操作
bkWorker.RunWorkerAsync();
}
}
...全文
1015 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
无情时尚 2017-09-04
  • 打赏
  • 举报
回复
不知道这样行不行
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private int num = 0;
        private void button1_Click(object sender, EventArgs e)
        {
            //只执行这一个方法更新界面
            ThreadUpdate(num+=10);
        }

        private void ThreadUpdate(int num)
        {
            //新开一个后台线程,并开始执行
            new Thread(delegate ()
            {
                UpdateBar(progressBar1, num);
                UpdateLab(label1, num);
            })
            { IsBackground = true }.Start();
        }

        private void UpdateBar(ProgressBar bar, int num)
        {
            new Action(() =>
            {
                //更新界面进度条的数值
                bar.Invoke(new Action(() =>
                {
                    if (num >= bar.Minimum && num <= bar.Maximum)
                        bar.Value = num;
                }));
            }).Invoke();
        }

        private void UpdateLab(Label lab, int str)
        {
            new Action(() =>
            {
                //更新界面Lab的数值
                lab.Invoke(new Action(() =>
                {
                    lab.Text = "处理进度: " + str + " %";
                }));
            }).Invoke();
        }
    }
}
楚楚3107 2017-09-01
  • 打赏
  • 举报
回复
引用 9 楼 xdashewan 的回复:
[quote=引用 3 楼 chulijun3107 的回复:] 这个我试过了。sleep中的时间长就效果就不那么明显了。500毫秒就没这问题了。能给我解释下为什么时间短会导致这个问题么。
我平时BackgroundWorker用的少,这个我倒还真不知道该如何解释,Thread线程中并不会发生你这样的现象,但我找到篇文章,和你的现象类似,但能不能解决你可以尝试下https://q.cnblogs.com/q/48151/[/quote]多谢帮忙了。
我不会发光i 2017-09-01
  • 打赏
  • 举报
回复
(⊙o⊙)哦, 那么你可以试着减少一部分数值,让进度条近似于弹框时刻..
易2017 2017-08-30
  • 打赏
  • 举报
回复
虽然你的问题我不懂,但类似进度条不同步,也许是因为你的设置的最大值和value绑定的步进最大值不一致
xdashewan 2017-08-30
  • 打赏
  • 举报
回复
引用 3 楼 chulijun3107 的回复:
这个我试过了。sleep中的时间长就效果就不那么明显了。500毫秒就没这问题了。能给我解释下为什么时间短会导致这个问题么。
我平时BackgroundWorker用的少,这个我倒还真不知道该如何解释,Thread线程中并不会发生你这样的现象,但我找到篇文章,和你的现象类似,但能不能解决你可以尝试下https://q.cnblogs.com/q/48151/
exception92 2017-08-30
  • 打赏
  • 举报
回复
e.ProgressPercentage 与 (int)(e.ProgressPercentage / percentValue) 计算方式不一样吧? 一个是报告值,一个是/percentValue的值。
我不会发光i 2017-08-30
  • 打赏
  • 举报
回复
你要给进度条设置一个最大,最小值,这样应该会同步的!
  • 打赏
  • 举报
回复
你可以把 this.progressBar1.Value 和 percent 使用 Debug.Print 打印在同一行上,然后贴出来。如果它们每一行的值是一致的,那说明你是眼睛看到的问题,而数值并没有问题。如果不一致那就是测试程序 bug。
  • 打赏
  • 举报
回复
哦, sorry,看错了,你是仅仅做一个 demo而不是显示进度。 可以肯定地是,写上 Sleep 绝不是应该的做法。如果进度条刷新显示本身就有延迟,那么你可以接受。如果它有很明显的延迟,那么你可以放弃使用进度条控件。 你应该调试一下看看设置进度条的代码是不是有 bug。
  • 打赏
  • 举报
回复
你怎么会在 ProcessProgress 中写一个循环语句?谁教你的啊?这个太诡异了吧。
楚楚3107 2017-08-30
  • 打赏
  • 举报
回复
这个我试过了。sleep中的时间长就效果就不那么明显了。500毫秒就没这问题了。能给我解释下为什么时间短会导致这个问题么。
xdashewan 2017-08-30
  • 打赏
  • 举报
回复
试试Sleep时间长点会不会好些

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧