此处为通用的进度条模板using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Threading;namespace UserControls
{
public partial class GuageBar : XtraUserControl
{
#region 属性
/// <summary>
/// 显示的信息
/// </summary>
public string ProgressMessage
{
set;
get;
}
private bool _isMaqueeBar = true;
/// <summary>
/// 是否是滚动进度条
/// </summary>
public bool isMaqueeBar
{
set { _isMaqueeBar = value; }
get { return _isMaqueeBar; }
} private ProgressState state= ProgressState.Running;
#endregion public GuageBar()
{
InitializeComponent();
} public void ShowProgress(object sender,ShowProgressArgs e)
{
//确认是否在UI线程上
if (this.InvokeRequired == false)
{
groupPro.Text = e.Value.ToString();
bar.Text = e.Value.ToString();
bar.Properties.Maximum = e.Max; e.Cancel = (state == ProgressState.Canceled); if (e.Cancel || (e.Value == e.Max))
{
state = ProgressState.None;
//结束进程
this.Dispose();
}
}
else
{
//异步显示进度.将控制传给UI线程
ShowProgressHandler showProgress = new ShowProgressHandler(ShowProgress);
Invoke(showProgress, new object[] {sender, e });
}
} public delegate void ShowProgressHandler(object sender,ShowProgressArgs e); private void Bar_load(object sender, EventArgs e)
{
this.Left = this.FindForm().Width / 2 - this.Width / 2;
this.Top = this.FindForm().Height / 2 - this.Height / 2;
this.BringToFront();
barMaquee.Text = ProgressMessage;
mutex(isMaqueeBar);
} private void btn_return_Click(object sender, EventArgs e)
{
state = ProgressState.Canceled;
} void mutex(bool visable)
{
bar.Visible = visable;
barMaquee.Visible = !visable;
}
} public class ShowProgressArgs : EventArgs
{
public string Text;
public int Max;
public int Value;
public bool Cancel; public ShowProgressArgs(string text,int max,int value)
{
this.Text = text;
this.Value = value;
this.Max = max;
}
} public enum ProgressState
{
None,
Canceled,
Running
}
}此处为form 开始调用...
private void btn_cal_Click(object sender, EventArgs e)
{
guageBar = new GuageBar();
this.Controls.Add(guageBar);
guageBar.Show(); CalcPiDelegate calcPi = new CalcPiDelegate(CalcPi);
//异步調用 IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); while (!res.IsCompleted) //IsCompleted的值一直为false
System.Threading.Thread.Sleep(10); MessageBox.Show(res.ToString());
此处永远执行不了.
}
delegate string CalcPiDelegate(int digits);
private string CalcPi(int digits)
{
//计算PI
StringBuilder pi = new StringBuilder("3", digits + 2); Object send = System.Threading.Thread.CurrentThread;
ShowProgressArgs e=new ShowProgressArgs("算PI", digits, 1); guageBar.ShowProgress(send, e);
if (digits > 0)
{
pi.Append(".");
for (int i = 0; i < digits; i += 9)
{
int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
int digitCount = Math.Min(digits - i, 9);
string ds = string.Format("{0:D9}", nineDigits);
pi.Append(ds.Substring(0, digitCount));
e.Value = i + digitCount;
guageBar.ShowProgress(send, e);
if (e.Cancel)
{
break ;
}
}
}
return pi.ToString();
}
....
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using System.Threading;namespace UserControls
{
public partial class GuageBar : XtraUserControl
{
#region 属性
/// <summary>
/// 显示的信息
/// </summary>
public string ProgressMessage
{
set;
get;
}
private bool _isMaqueeBar = true;
/// <summary>
/// 是否是滚动进度条
/// </summary>
public bool isMaqueeBar
{
set { _isMaqueeBar = value; }
get { return _isMaqueeBar; }
} private ProgressState state= ProgressState.Running;
#endregion public GuageBar()
{
InitializeComponent();
} public void ShowProgress(object sender,ShowProgressArgs e)
{
//确认是否在UI线程上
if (this.InvokeRequired == false)
{
groupPro.Text = e.Value.ToString();
bar.Text = e.Value.ToString();
bar.Properties.Maximum = e.Max; e.Cancel = (state == ProgressState.Canceled); if (e.Cancel || (e.Value == e.Max))
{
state = ProgressState.None;
//结束进程
this.Dispose();
}
}
else
{
//异步显示进度.将控制传给UI线程
ShowProgressHandler showProgress = new ShowProgressHandler(ShowProgress);
Invoke(showProgress, new object[] {sender, e });
}
} public delegate void ShowProgressHandler(object sender,ShowProgressArgs e); private void Bar_load(object sender, EventArgs e)
{
this.Left = this.FindForm().Width / 2 - this.Width / 2;
this.Top = this.FindForm().Height / 2 - this.Height / 2;
this.BringToFront();
barMaquee.Text = ProgressMessage;
mutex(isMaqueeBar);
} private void btn_return_Click(object sender, EventArgs e)
{
state = ProgressState.Canceled;
} void mutex(bool visable)
{
bar.Visible = visable;
barMaquee.Visible = !visable;
}
} public class ShowProgressArgs : EventArgs
{
public string Text;
public int Max;
public int Value;
public bool Cancel; public ShowProgressArgs(string text,int max,int value)
{
this.Text = text;
this.Value = value;
this.Max = max;
}
} public enum ProgressState
{
None,
Canceled,
Running
}
}此处为form 开始调用...
private void btn_cal_Click(object sender, EventArgs e)
{
guageBar = new GuageBar();
this.Controls.Add(guageBar);
guageBar.Show(); CalcPiDelegate calcPi = new CalcPiDelegate(CalcPi);
//异步調用 IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); while (!res.IsCompleted) //IsCompleted的值一直为false
System.Threading.Thread.Sleep(10); MessageBox.Show(res.ToString());
此处永远执行不了.
}
delegate string CalcPiDelegate(int digits);
private string CalcPi(int digits)
{
//计算PI
StringBuilder pi = new StringBuilder("3", digits + 2); Object send = System.Threading.Thread.CurrentThread;
ShowProgressArgs e=new ShowProgressArgs("算PI", digits, 1); guageBar.ShowProgress(send, e);
if (digits > 0)
{
pi.Append(".");
for (int i = 0; i < digits; i += 9)
{
int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
int digitCount = Math.Min(digits - i, 9);
string ds = string.Format("{0:D9}", nineDigits);
pi.Append(ds.Substring(0, digitCount));
e.Value = i + digitCount;
guageBar.ShowProgress(send, e);
if (e.Cancel)
{
break ;
}
}
}
return pi.ToString();
}
....
System.Threading.Thread.Sleep(10);如果没有上面这行, 则能够执行 MessageBox.Show(res.ToString());
且页面进度条也正常.
IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null);这句话有问题吗?
其实你这个,跟同步没什么区别,何苦非要Invoke你应该EndInvoke来判断,并返回结果值。你应该这样:
IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); // 这行我没有管你对不对呵。// 在回调函数执行完之间,下一句将不断阻塞调用者线程,直到返回结果
string result = (string)calcPi.EndInvoke ( res );// 然后那个 result 就是你想要的结果……
我不知道你为什么不直接用同步 Invoke ……非要这么费事儿。
这行没有问题. 如果同步, calcPi.Invoke((int)spin_nums.Value);
则要运行完成, 才到下一步, 在运行时,不会把guageBar显示出来.IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); // 这行我没有管你对不对呵。执行后,出现的情况,就像死循环一下. 不动了.如果没有string result = (string)calcPi.EndInvoke ( res );这行, 就正常如下.
private void Input2_Load(object sender, EventArgs e)
{
this.guageBar.onDoWork += new GuageBar.doWorkHandle(guageBar_onDoWork);
this.guageBar.onWorkerCompleted += new GuageBar.WorkerCompletedHandle(guageBar_onWorkerCompleted);
} void guageBar_onWorkerCompleted(BackgroundWorker sender, RunWorkerCompletedEventArgs e)
{
this.txt_msg.Text = e.Result.ToString();
} void guageBar_onDoWork(BackgroundWorker sender, DoWorkEventArgs e)
{
e.Result = CalcPi((int)spin_nums.Value, sender, e);
} private void btn_cal_Click(object sender, EventArgs e)
{
guageBar.Show();
guageBar.ProgressMessage = "正在计算Pi的值";
guageBar.RunWork();
} private string CalcPi(int digits,BackgroundWorker work,DoWorkEventArgs e)
{ StringBuilder pi = new StringBuilder("3", digits + 2);
if (digits > 0)
{
pi.Append(".");
for (int i = 0; i < digits; i += 9)
{
if (work.CancellationPending)
{
e.Cancel = true;
break;
} int nineDigits = NineDigitsOfPi.StartingAt(i + 1);
int digitCount = Math.Min(digits - i, 9);
string ds = string.Format("{0:D9}", nineDigits);
pi.Append(ds.Substring(0, digitCount));
int rrr = ((i + digitCount) * 100 / digits);
work.ReportProgress(rrr);
}
}
return pi.ToString();
}
.........
guagebar.cs 组件代码 /// <summary>
/// 进度条组件
/// </summary>
public partial class GuageBar : XtraUserControl
{
#region 属性
/// <summary>
/// 显示的信息
/// </summary>
public string ProgressMessage
{
set { groupPro.Text = value; }
get { return groupPro.Text; }
}
private bool _isMaqueeBar = true;
/// <summary>
/// 是否是滚动进度条
/// </summary>
public bool isMaqueeBar
{
set { _isMaqueeBar = value; }
get { return _isMaqueeBar; }
} protected BackgroundWorker Worker = new BackgroundWorker(); /// <summary>
/// 公布异步处理的方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void WorkerCompletedHandle(BackgroundWorker sender, RunWorkerCompletedEventArgs e);
public delegate void doWorkHandle(BackgroundWorker sender, DoWorkEventArgs e); public event WorkerCompletedHandle onWorkerCompleted;
public event doWorkHandle onDoWork; #endregion public GuageBar()
{
InitializeComponent();
Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
Worker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged);
}
/// <summary>
/// 报告进度
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.bar.Text = e.ProgressPercentage.ToString();
this.lbl_tip.Text = this.bar.Text;
}
/// <summary>
/// 后台进程完成
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
if (e.Cancelled)
{
this.Visible = false;
return;
}
if (onWorkerCompleted != null)
{
onWorkerCompleted(worker, e);
}
if (this.Visible)
{
this.Visible = false;
}
}
/// <summary>
/// 开始执行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Worker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
if (onDoWork != null)
{
onDoWork(worker, e);
}
}
/// <summary>
/// 公布方法,异步处理
/// </summary>
public void RunWork()
{
if (Worker.IsBusy)
{
MessageBox.Show("正在进行异步操作, 请等待!");
return;
}
Worker.RunWorkerAsync(null);
}
/// <summary>
/// 组件load时,置中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Bar_load(object sender, EventArgs e)
{
if (!DesignMode)
{
this.Left = this.FindForm().Width / 2 - this.Width / 2;
this.Top = this.FindForm().Height / 2 - this.Height / 2;
this.BringToFront();
barMaquee.Text = ProgressMessage;
mutex(isMaqueeBar);
//可以取消,和报告进度
Worker.WorkerSupportsCancellation = true;
Worker.WorkerReportsProgress = true;
}
}
/// <summary>
/// 再次显示时,重置按钮等状态
/// </summary>
/// <param name="e"></param>
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
if (this.Visible)
{
btn_return.Enabled = true;
bar.Text = "0";
}
}
/// <summary>
/// 取消操作
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btn_return_Click(object sender, EventArgs e)
{ Worker.CancelAsync();
btn_return.Enabled = false;
}
/// <summary>
/// 互拆状态
/// </summary>
/// <param name="visable"></param>
void mutex(bool visable)
{
bar.Visible = visable;
barMaquee.Visible = !visable;
}
}
感谢hikaliv, 和其他回帖的朋友