首页 新闻 会员 周边

多线程进度条问题

0
悬赏园豆:180 [已解决问题] 解决于 2009-06-25 16:27

在一个WinForm窗体上有三个进度条(分别为a,b,c)和一个Button按钮,点击按钮,程序开始运行,当a走100%时,b走10%,c走1%。请问这个程序要怎么写?

问题补充: 补充说明:三个进度条同时在走,但是a走的快,b其次,c最慢。走的百分比按题目中所说。希望能给出个可以运行的代码。这可是我仅有的200分中的180分啊! 再次补充:“Galactica”这位朋友的程序,存在些问题,当a走完时,b,c就停了。这不是我想要的。应该是a走完后,b继续,c也继续。每个进度条走完后,保持满格最大值,没有走完的继续走。
DongLiYang的主页 DongLiYang | 初学一级 | 园豆:22
提问于:2009-06-17 17:44
< >
分享
最佳答案
0

首先你要对线程有一定的了解。进度条的显示、后台的进度计算是在两个线程里面分别来运行的。不然会出现不同步的问题。

然后是委托。用委托来进行两个线程之间的通信。

至于三个进度条,简单:直接在计算进度的线程中,算好的进度,直接给主线程a走100%时,b走10%,c走1%,百分知多少就是参数的问题。

如果你的重点是 “a走100%时,b走10%,c走1%”。你只要在得到百分比的算法上作文章了。

比如:a的工作量:循环100次,那么b循环1000次,c循环10000次。那么同等时间里就是你要的效果。

明白吧。这个功能在vs2005 中,有个控件是做个的。一个是那个进度条控件,一个就是 back..的控件。图标很好认有半个进度条。

给分吧

补充例子:

namespace Pro
{
    delegate void setprogressBar(int prent, string rogressBar_name);
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            //声明委托对象
            setprogressBar set = new setprogressBar(SetValue);
            //进度条的计算、直接用循环代替后台的操作。
            for (int i = 0; i < 10000; i++)
            {
                //跨线程调用
                this.Invoke(set, new object[] { i / 100, "a" });
                this.Invoke(set, new object[] { i / 1000, "b" });
                this.Invoke(set, new object[] { i / 10000, "c" });
            }
        }
        /// <summary>
        /// 测试开始
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            this.backgroundWorker1.RunWorkerAsync();
        }
        /// <summary>
        /// 主线程中设置进度数值
        /// </summary>
        /// <param name="prent">百分比</param>
        /// <param name="name">控件名称</param>
        private void SetValue(int prent, string name)
        {
            switch (name)
            {
                case "a":
                    this.progressBar1.Value = prent;
                    break;
                case "b":
                    this.progressBar2.Value = prent;
                    break;
                case "c":
                    this.progressBar3.Value = prent;
                    break;
            }
        }
    }
}

页面拖拽控件代码省略。

邢少 | 专家六级 |园豆:10926 | 2009-06-17 18:11
其他回答(4)
0

设定主心跳 t int,可取时钟等。

a 取 t * 100 > 100 ? 100 : t * 100;

b 取 t * 10   > 100 ? 100 : t * 10;

c 取 t > 100 ? 100 : t;

搓吧,哈哈?

陛下 | 园豆:3938 (老鸟四级) | 2009-06-17 17:54
0

给三个控件设置Maximum时,按比例设置:
A:100
B:1000
C:10000
值溢出时归0.

I,Robot | 园豆:9783 (大侠五级) | 2009-06-17 18:03
0

呵呵,楼主貌似实际的程序应该不会你举的例子那样精确吧;

个人认为这三者不简单的数字关系,而是有很大的业务逻辑在里面,类似WINRAR的进度条,大不了用三个backgroundWorker 分别处理三个进度条;

winzheng | 园豆:8797 (大侠五级) | 2009-06-17 18:44
0

由于时间仓促,给出简单实现,没有太多的考虑.本代码实现楼主要的效果.

 1,三个 ProgressBar;

2,ProgressBar1 走 100 后通知 ProgressBar2 , ProgressBar1 Sleep 100 毫秒后重复该工作;

3,ProgressBar2 收到 ProgressBar1 的通知后走 10 ,然后通知 ProgressBar3,最后等待;

4,ProgressBar3 收到 ProgressBar2 的通知后 走 1 ,然后等待;

 

public class WorkerBar
{
private EventWaitHandle _event;
private EventWaitHandle _parentEvent;
private ProgressBar _bar;

public WorkerBar(ProgressBar bar,EventWaitHandle eventHandle,EventWaitHandle parentEventHandle)
{
this._bar = bar;
this._event = eventHandle;
this._parentEvent = parentEventHandle;
}

private delegate void PerformStepDelegate(ProgressBar progressBar);

public void PerformStep(ProgressBar progressBar)
{
if (!progressBar.InvokeRequired)
{
progressBar.PerformStep();
}
else
{
PerformStepDelegate performStep
= new PerformStepDelegate(this.PerformStep);
progressBar.Invoke(performStep,
new object[] { progressBar });
}
}

public EventWaitHandle Event
{
get
{
return this._event;
}
}

public EventWaitHandle ParentEvent
{
get
{
return this._parentEvent;
}
}

public ProgressBar Bar
{
get
{
return this._bar;
}
}
}

 

public partial class Form1 : Form
{
private List<WorkerBar> _workerBars;
private WaitHandle[] _waitEvents;

public Form1()
{
InitializeComponent();

_workerBars
= new List<WorkerBar>();
_waitEvents
= new WaitHandle[3];
}

private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 3; i++)
{
_waitEvents[i]
= new ManualResetEvent(false);
}

_workerBars.Add(
new WorkerBar(this.progressBar1, (EventWaitHandle)_waitEvents[0], (EventWaitHandle)_waitEvents[1]));
_workerBars.Add(
new WorkerBar(this.progressBar2, (EventWaitHandle)_waitEvents[1], (EventWaitHandle)_waitEvents[2]));
_workerBars.Add(
new WorkerBar(this.progressBar3, (EventWaitHandle)_waitEvents[2], (EventWaitHandle)_waitEvents[0]));

Thread th1
= new Thread(ProgressBar1ThreadProc);
Thread th2
= new Thread(ProgressBar2ThreadProc);
Thread th3
= new Thread(ProgressBar3ThreadProc);

th1.Start(_workerBars[
0]);
th2.Start(_workerBars[
1]);
th3.Start(_workerBars[
2]);
}

/// <summary>
/// 工作线程 1
/// </summary>
private static void ProgressBar1ThreadProc(object obj)
{
WorkerBar workerBar
= (WorkerBar)obj;

while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
Thread.Sleep(
100);

workerBar.PerformStep(workerBar.Bar);

workerBar.ParentEvent.Set();
//通知工作线程 1
}
}

/// <summary>
/// 工作线程 2
/// </summary>
private static void ProgressBar2ThreadProc(object obj)
{
WorkerBar workerBar
= (WorkerBar)obj;

while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
workerBar.Event.WaitOne();
//等待工作线程 1 通知

workerBar.PerformStep(workerBar.Bar);

workerBar.Event.Reset();
workerBar.ParentEvent.Set();
//通知工作线程 3
}
}

/// <summary>
/// 工作线程 3
/// </summary>
private static void ProgressBar3ThreadProc(object obj)
{
WorkerBar workerBar
= (WorkerBar)obj;

while (workerBar.Bar.Value != workerBar.Bar.Maximum)
{
workerBar.Event.WaitOne();
//等待工作线程 2 通知

workerBar.PerformStep(workerBar.Bar);

workerBar.Event.Reset();
}
}
}

 

partial class Form1
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows 窗体设计器生成的代码

/// <summary>
/// 设计器支持所需的方法 - 不要
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.progressBar1 = new System.Windows.Forms.ProgressBar();
this.progressBar2 = new System.Windows.Forms.ProgressBar();
this.progressBar3 = new System.Windows.Forms.ProgressBar();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(578, 42);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// progressBar1
//
this.progressBar1.Location = new System.Drawing.Point(12, 42);
this.progressBar1.Maximum = 1000;
this.progressBar1.Name = "progressBar1";
this.progressBar1.Size = new System.Drawing.Size(533, 23);
this.progressBar1.Step = 100;
this.progressBar1.TabIndex = 1;
//
// progressBar2
//
this.progressBar2.Location = new System.Drawing.Point(12, 107);
this.progressBar2.Maximum = 1000;
this.progressBar2.Name = "progressBar2";
this.progressBar2.Size = new System.Drawing.Size(533, 23);
this.progressBar2.TabIndex = 1;
//
// progressBar3
//
this.progressBar3.Location = new System.Drawing.Point(12, 163);
this.progressBar3.Maximum = 1000;
this.progressBar3.Name = "progressBar3";
this.progressBar3.Size = new System.Drawing.Size(533, 23);
this.progressBar3.Step = 1;
this.progressBar3.TabIndex = 1;
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(689, 366);
this.Controls.Add(this.progressBar3);
this.Controls.Add(this.progressBar2);
this.Controls.Add(this.progressBar1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.Button button1;
private System.Windows.Forms.ProgressBar progressBar1;
private System.Windows.Forms.ProgressBar progressBar2;
private System.Windows.Forms.ProgressBar progressBar3;
}
                        
Launcher | 园豆:45045 (高人七级) | 2009-06-17 21:23
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册