/// <summary> /// Start a background task /// </summary> /// <param name="argument"></param> /// <param name="app"></param> public static void Start(object argument, BackgroundWorkerToolStripInfo app) { #region Set your CancelButton, ProgressBar, and StatusLabel here... Form activeForm = app.ActiveForm; Button cancelButton = app.CancelButton; ToolStripProgressBar progressBar = app.ProgressBar; ToolStripLabel statusLabel = app.StatusLabel; // disable these controls when running... Control[] userControls = app.DisableControls; #endregion bool isRunning = false; EventHandler cancel = null; FormClosingEventHandler formClosing = null; BackgroundTask.Start( argument, delegate(object sender, DoWorkEventArgs e) //(object sender, DoWorkEventArgs e) => { #region DoWorkEventHandler - main code goes here... // IMPORTANT: Do not access any GUI controls here. (This code is running in the background thread!) var w = (BackgroundWorker)sender; Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; StatusReport sr = new StatusReport(); sr.SetBackgroundWorker(w, e, 1); app.Callback(new BackgroundWorkerEventArgs(w, e, sr)); #endregion }, delegate(object sender, EventArgs e) //(object sender, DoWorkEventArgs e) => { #region EventHandler - initialize code goes here... // It is safe to access the GUI controls here... if (progressBar != null) { progressBar.Visible = true; progressBar.Minimum = progressBar.Maximum = progressBar.Value = 0; } isRunning = true; #region Hookup event handlers for Button.Canceland Form.FormClosing var w = sender as BackgroundWorker; if (w != null && w.WorkerSupportsCancellation) { if (cancelButton != null) { cancel = (object sender2, EventArgs e2) => { //var w = sender2 as BackgroundWorker; string msg = "The application is still busy processing. Do you want to stop it now?"; if (MessageBox.Show(msg, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { w.CancelAsync(); } }; cancelButton.Click += cancel; cancelButton.Enabled = true; } } // also, confirm the user if the user clicks the close button. if (activeForm != null) { formClosing = (object sender2, FormClosingEventArgs e2) => { if (!isRunning) { return; } string msg = "The application is still busy processing. Do you want to close the application anyway?"; e2.Cancel = MessageBox.Show(msg, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.Yes; }; activeForm.FormClosing += formClosing; } #endregion if (activeForm != null) { FormUtil.Busy(activeForm, userControls, true); } #endregion }, delegate(object sender, ProgressChangedEventArgs e) //(object sender, ProgressChangedEventArgs e) => { #region ProgressChangedEventHandler - update progress code goes here... // It is safe to access the GUI controls here... var sr = e.UserState as StatusReport; if (sr == null) { return; } if (progressBar != null) { StatusReport.UpdateStatusReport(progressBar, sr); } if (statusLabel != null) { statusLabel.Text = sr.ToString(); } #endregion }, delegate(object sender, RunWorkerCompletedEventArgs e) //(object sender, RunWorkerCompletedEventArgs e) => { #region RunWorkerCompletedEventHandler - cleanup code goes here... // It is safe to access the GUI controls here... try { if (e.Error != null) { throw e.Error; } if (e.Cancelled) { throw new ThreadInterruptedException("Thread was interrupted by the user."); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), ex.Message); } finally { if (activeForm != null) { FormUtil.Busy(activeForm, userControls, false); } if (progressBar != null) { progressBar.Visible = false; } if (statusLabel != null) { statusLabel.Text = "Ready"; } if (cancel != null) { cancelButton.Click -= cancel; cancelButton.Enabled = false; } if (formClosing != null) { activeForm.FormClosing -= formClosing; } isRunning = false; } #endregion }); }
private void Start2(object argument) { /* * Create anonymous (using delegates using lamda expressions) * */ #region Set your CancelButton, ProgressBar, and StatusLabel here... Form activeForm = null; // set myForm=this; Button cancelButton = new Button(); ToolStripProgressBar progressBar = new ToolStripProgressBar(); ToolStripLabel statusLabel = new ToolStripLabel(); // disable these controls when running... Control[] userControls = null; #endregion bool isRunning = false; EventHandler cancel = null; FormClosingEventHandler formClosing = null; DoWorkEventHandler doWork = delegate(object sender, DoWorkEventArgs e) //(object sender, DoWorkEventArgs e) => { #region DoWorkEventHandler - main code goes here... // IMPORTANT: Do not access any GUI controls here. (This code is running in the background thread!) var w = (BackgroundWorker)sender; //Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; if (false) // code sample { int max = (int)e.Argument; StatusReport sr = new StatusReport(); sr.SetBackgroundWorker(w, e, 1); sr.ReportProgress("Processing...", 0, max, 0); for (int i = 0; i < max; i++) { sr.Value++; sr.ReportProgress(); } sr.ReportProgress("Done"); } #endregion }; EventHandler doInit = delegate(object sender, EventArgs e) //(object sender, DoWorkEventArgs e) => { #region EventHandler - initialize code goes here... // It is safe to access the GUI controls here... progressBar.Visible = true; progressBar.Minimum = progressBar.Maximum = progressBar.Value = 0; isRunning = true; #region Hookup event handlers for Button.Canceland Form.FormClosing var w = sender as BackgroundWorker; if (w != null && w.WorkerSupportsCancellation) { if (cancelButton != null) { cancel = (object sender2, EventArgs e2) => { //var w = sender2 as BackgroundWorker; string msg = "The application is still busy processing. Do you want to stop it now?"; if (MessageBox.Show(msg, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes) { w.CancelAsync(); } }; cancelButton.Click += cancel; cancelButton.Enabled = true; } } // also, confirm the user if the user clicks the close button. if (activeForm != null) { formClosing = (object sender2, FormClosingEventArgs e2) => { if (!isRunning) { return; } string msg = "The application is still busy processing. Do you want to close the application anyway?"; e2.Cancel = MessageBox.Show(msg, "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) != DialogResult.Yes; }; activeForm.FormClosing += formClosing; } #endregion FormUtil.Busy(activeForm, userControls, true); #endregion }; ProgressChangedEventHandler doProgress = delegate(object sender, ProgressChangedEventArgs e) //(object sender, ProgressChangedEventArgs e) => { #region ProgressChangedEventHandler - update progress code goes here... // It is safe to access the GUI controls here... var sr = e.UserState as StatusReport; if (sr == null) { return; } StatusReport.UpdateStatusReport(progressBar, sr); statusLabel.Text = sr.ToString(); #endregion }; RunWorkerCompletedEventHandler doComplete = delegate(object sender, RunWorkerCompletedEventArgs e) //(object sender, RunWorkerCompletedEventArgs e) => { #region RunWorkerCompletedEventHandler - cleanup code goes here... // It is safe to access the GUI controls here... try { if (e.Error != null) { throw e.Error; } if (e.Cancelled) { throw new ThreadInterruptedException("Thread was interrupted by the user."); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), ex.Message); } finally { FormUtil.Busy(activeForm, userControls, false); progressBar.Visible = false; if (cancel != null) { cancelButton.Click -= cancel; cancelButton.Enabled = false; } if (formClosing != null) { activeForm.FormClosing -= formClosing; } isRunning = false; statusLabel.Text = "Ready"; } #endregion }; BackgroundTask.Start(argument, doWork, doInit, doProgress, doComplete); }
/// <summary> /// start the process in multiple threads, wait for completion, and merge output. /// </summary> public void StartAsync() { BackgroundTask.Start( null, delegate(object sender, DoWorkEventArgs e) { // main code goes here... try { manager.StartAsync(); } catch (Exception ex) { throw ex; } }, delegate(object sender, EventArgs e) { // initialize code goes here... this.confirmExit = true; this.btnOkay.Enabled = false; this.btnCancel.Enabled = true; Message = "Please wait while processing..."; Title = "Task Running..."; }, delegate(object sender, ProgressChangedEventArgs e) { // update progress code goes here... }, delegate(object sender, RunWorkerCompletedEventArgs e) { // cleanup code goes here... this.confirmExit = false; this.btnOkay.Enabled = true; this.btnCancel.Enabled = false; int errors = manager.Log.Length; if (errors == 0 && this.CloseOnCompletion) { btnOkay_Click(sender, EventArgs.Empty); } if (errors == 0) { Title = "Task Completed"; Message = "The task completed successfully. Click OK to continue."; } else { Title = "Task Completed With Errors"; Message = string.Format("There were {0} errors. Click the ERROR tab for more detail.", errors); btnShowDetail.Tag = true; btnShowDetail_Click(this, EventArgs.Empty); } Error = StringUtil.StringArrayToString(manager.Log, string.Format("{0}{0}{1}{0}", Environment.NewLine, "".PadRight(40, '-'))); }); }