此处为通用的进度条模板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();
        }
....

解决方案 »

  1.   

     while (!res.IsCompleted) //IsCompleted的值一直为false 
                    System.Threading.Thread.Sleep(10);如果没有上面这行, 则能够执行 MessageBox.Show(res.ToString());
    且页面进度条也正常.
      

  2.   


      IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null);这句话有问题吗?
      

  3.   

    问题很明显……while (!res.IsCompleted) //IsCompleted的值一直为false 
    其实你这个,跟同步没什么区别,何苦非要Invoke你应该EndInvoke来判断,并返回结果值。你应该这样:
    IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); // 这行我没有管你对不对呵。// 在回调函数执行完之间,下一句将不断阻塞调用者线程,直到返回结果
    string result = (string)calcPi.EndInvoke ( res );// 然后那个 result 就是你想要的结果……
    我不知道你为什么不直接用同步 Invoke ……非要这么费事儿。
      

  4.   

    你未调用 EndInvoke 之前 res 的 IsComplete 域是不会置真的
      

  5.   


    这行没有问题. 如果同步,  calcPi.Invoke((int)spin_nums.Value);
    则要运行完成, 才到下一步, 在运行时,不会把guageBar显示出来.IAsyncResult res = calcPi.BeginInvoke((int)spin_nums.Value,null,null); // 这行我没有管你对不对呵。执行后,出现的情况,就像死循环一下. 不动了.如果没有string result = (string)calcPi.EndInvoke ( res );这行, 就正常如下.
      

  6.   

    为什么到这一行string result = (string)calcPi.EndInvoke ( res )就死循环了呢? 是不是res一直在运行,如果没有运行结束, 就一直等待. 那是不是线程之间处于竟争状态?
      

  7.   

    不用是正常的,EndInvoke 就是将线程阻塞了。给你一个建议吧。像这种异步用PROGRESSBAR的,你可以参考一个组件,叫做 BackgroundWorker……我一直用它……,否则,你最好自己进行完整的Thread操作。http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(VS.80).aspx
      

  8.   

    既然BeginInvoke,为啥不用EndInvode的,要不就不是异步了捏
      

  9.   

    研究了一下BackgroundWorker,基本能满足需求了.form代码....
            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,  和其他回帖的朋友