Display progress bar while doing some work in C#?

后端 未结 13 2014
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-27 12:07

I want to display a progress bar while doing some work, but that would hang the UI and the progress bar won\'t update.

I have a WinForm ProgressForm with a Pro

13条回答
  •  半阙折子戏
    2020-11-27 13:03

    We are use modal form with BackgroundWorker for such a thing.

    Here is quick solution:

      public class ProgressWorker : BackgroundWorker where TArgument : class 
        {
            public Action Action { get; set; }
    
            protected override void OnDoWork(DoWorkEventArgs e)
            {
                if (Action!=null)
                {
                    Action(e.Argument as TArgument);
                }
            }
        }
    
    
    public sealed partial class ProgressDlg : Form where TArgument : class
    {
        private readonly Action action;
    
        public Exception Error { get; set; }
    
        public ProgressDlg(Action action)
        {
            if (action == null) throw new ArgumentNullException("action");
            this.action = action;
            //InitializeComponent();
            //MaximumSize = Size;
            MaximizeBox = false;
            Closing += new System.ComponentModel.CancelEventHandler(ProgressDlg_Closing);
        }
        public string NotificationText
        {
            set
            {
                if (value!=null)
                {
                    Invoke(new Action(s => Text = value));  
                }
    
            }
        }
        void ProgressDlg_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            FormClosingEventArgs args = (FormClosingEventArgs)e;
            if (args.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
            }
        }
    
    
    
        private void ProgressDlg_Load(object sender, EventArgs e)
        {
    
        }
    
        public void RunWorker(TArgument argument)
        {
            System.Windows.Forms.Application.DoEvents();
            using (var worker = new ProgressWorker {Action = action})
            {
                worker.RunWorkerAsync();
                worker.RunWorkerCompleted += worker_RunWorkerCompleted;                
                ShowDialog();
            }
        }
    
        void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                Error = e.Error;
                DialogResult = DialogResult.Abort;
                return;
            }
    
            DialogResult = DialogResult.OK;
        }
    }
    

    And how we use it:

    var dlg = new ProgressDlg(obj =>
                                      {
                                         //DoWork()
                                         Thread.Sleep(10000);
                                         MessageBox.Show("Background task completed "obj);
                                       });
    dlg.RunWorker("SampleValue");
    if (dlg.Error != null)
    {
      MessageBox.Show(dlg.Error.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    dlg.Dispose();
    

提交回复
热议问题