|
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace Library
{
public interface IThreadedExecuterView
{
void SetWait(bool isEnabled);
void HandleException(Exception ex);
}
public delegate T ThreadedExecuterDelegate<T>();
/// <summary>
/// Class to encapsulate frequently needed action in background thread with hourglass and disabled form,
/// then use results frombackground thread, then do something immediately after
/// </summary>
/// <typeparam name="T"></typeparam>
public class ThreadedExecuter<T> : IDisposable
{
public ThreadedExecuter()
{
}
public ThreadedExecuter(IThreadedExecuterView View)
{
this.View = View;
}
BackgroundWorker worker = null;
IThreadedExecuterView View = null;
//for value types use default instead of null since won't be valid when casting, will alows us to use int, etc. in addition to classes
T actionValue = default(T);
public ThreadedExecuter<T> Process(ThreadedExecuterDelegate<T> GetResultsAction)
{
View.SetWait(false);
worker = new BackgroundWorker();
worker.DoWork += new DoWorkEventHandler(delegate(object sender, DoWorkEventArgs e)
{
try
{
e.Result = GetResultsAction();
}
catch (Exception ex)
{
View.HandleException(ex);
}
});
return this;
}
public ThreadedExecuter<T> WhenFinished(Action<T> ProcessResultsAction)
{
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object sender, RunWorkerCompletedEventArgs e)
{
if (e != null && e.Result != null)
actionValue = (T)e.Result;
//if any end action and want to continue, call it
//want the results action to continue to wait until done
//but want post action to not be within wait
try
{
ProcessResultsAction(actionValue);
}
finally
{
//don't ever want to allow this to get an exception so we can get endinvoke exception
//want to make sure we stop from waiting, even on error
try { View.SetWait(true); }
catch (Exception ex) { Console.WriteLine("Error setting view wait: " + ex.ToString()); }
}
});
return this;
}
Action FinallyDelegate = null;
public ThreadedExecuter<T> Finally(Action FinallyDelegate)
{
this.FinallyDelegate = FinallyDelegate;
return this;
}
public ThreadedExecuter<T> Run()
{
//callpost action if any
if (FinallyDelegate != null)
{
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(delegate(object sender, RunWorkerCompletedEventArgs e)
{
try {
FinallyDelegate();
}
catch (Exception ex)
{
View.HandleException(ex);
}
});
}
worker.RunWorkerAsync();
return this;
}
public void Dispose()
{
if (worker != null)
worker.Dispose();
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I've been a software developer since 1996 and have enjoyed C# since 2003. I have a Bachelor's degree in Computer Science and for some reason, a Master's degree in Business Administration. I currently do software development contracting/consulting.