I have legacy code which performs some very long operations on the UI thread. What I want to do is to show a progress bar with message and run the work on another thread. Unfortunately , for now I don't have access to VS2012 so I can't use the async keyword. I've written some code which works fine with operations of 0-1 parameters and no return value using Action. But when I tried adjusting it to support Func I encountered some issues with invoking the tasks and returning TResult. Attached is my original code, would appreciate any suggestions. Thanks, Omer
public partial class FreeProgressBarFrm : System.Windows.Forms.Form { #region Members /// <summary> /// timer for the progress bar. /// </summary> private Timer m_Timer = new Timer(); /// <summary> /// Delegate for the background operation to perform. /// </summary> private Action m_backgroundOperation; /// <summary> /// Standard operation to show the user while the operation is in progress. /// </summary> private static readonly string m_performingUpdatesMessage = IO_Global.GetResourceString("Performing updates, please wait", "Performing updates, please wait", null); #endregion #region Constructor /// <summary> /// Constructor /// </summary> /// <param name="backgroundDelegate"> Delegate for the background operation to perform</param> /// <param name="operationName">meessage to show the user while the operation is in progress.</param> public FreeProgressBarFrm(Action backgroundDelegate, string operationName) { InitializeComponent(); m_backgroundOperation = backgroundDelegate; this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.lblOperation.Text = operationName; m_Timer.Interval = 1000; m_Timer.Tick += new EventHandler(m_Timer_Tick); } /// <summary> /// Constructor , for progressbar with defalt user message (performing updates, please wait). /// </summary> /// <param name="backgroundDelegate"> Delegate for the background operation to perform</param> /// <param name="operationName">operation display name</param> public FreeProgressBarFrm(Action backgroundDelegate): this(backgroundDelegate, m_performingUpdatesMessage) { } #endregion #region Methods /// <summary> /// Call this method to begin backgorund operation while /// showing the progress bar to the client. /// </summary> public void Wait() { ShowDialog(ControlsHelper.MainFrm); } /// <summary> /// Advance the progress bar /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void m_Timer_Tick(object sender, EventArgs e) { PerformStep(); } /// <summary> /// Advance the progress bar /// </summary> private void PerformStep() { this.progressBar1.PerformStep(); this.lblOperation.Refresh(); if (this.progressBar1.Value == this.progressBar1.Maximum) { this.progressBar1.Value = this.progressBar1.Minimum; } } /// <summary> /// Load the form , start the progress bar and backroud task. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ProgressBarFrm_Load(object sender, EventArgs e) { m_Timer.Start(); this.lblOperation.Refresh(); Task task = new Task(m_backgroundOperation); Task UITask = task.ContinueWith(delegate { OnWorkCompleted(); }, TaskScheduler.FromCurrentSynchronizationContext()); try { task.Start(); } catch (Exception) { Close(); throw; } } /// <summary> /// Called when the work has been completed. /// </summary> private void OnWorkCompleted() { Close(); } /// <summary> /// Close the timer. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ProgressBarFrm_FormClosing(object sender, FormClosingEventArgs e) { if (m_Timer != null) { m_Timer.Dispose(); m_Timer = null; } } #endregion }