|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;
namespace ThreadingComponent
{
/// <summary>
/// This ViewModel contains all the data required to run a work delegate
/// (the TaskFunc Func<Dictionary<String,Object>,ThreadableItem<T>>) and also
/// exposes methods to allow the work delegate to be run on a new thread. The
/// Data obtained by running the background thread is exposed on the Data
/// property, and the BgWorker is also exposed as a property so that it can be
/// used within Unit tests.
/// </summary>
/// <typeparam name="T">The return type of the threading operation</typeparam>
public class ThreadableItemViewModel<T> : ThreadableItemViewModelBase
{
#region Data
private ThreadableItem<T> data;
private Func<Dictionary<String,Object>,ThreadableItem<T>> taskFunc;
private BackgroundTaskManager<ThreadableItem<T>> bgWorker;
private Dictionary<String, Object> parameters = null;
#endregion
#region Private Methods
/// <summary>
/// Sets up the actual BackgroundTaskManager<T> component
/// </summary>
private void SetupWorker()
{
if (taskFunc == null)
throw new NullReferenceException("TaskFunc can not be null");
bgWorker = new BackgroundTaskManager<ThreadableItem<T>>(
() =>
{
return taskFunc(Parameters);
},
(result) =>
{
Data = result;
});
BgWorker.BackgroundTaskStarted -= BackgroundTaskStarted;
BgWorker.BackgroundTaskCompleted -= BackgroundTaskCompleted;
BgWorker.BackgroundTaskStarted += BackgroundTaskStarted;
BgWorker.BackgroundTaskCompleted += BackgroundTaskCompleted;
}
/// <summary>
/// Event that is raised when the background work is Completed. This event
/// is raised by the internal BackgroundTaskManager<T> component
/// </summary>
private void BackgroundTaskCompleted(object sender, EventArgs args)
{
//The order that these properties IS IMPORTANT, as it dictates
//which Adorner will be shown
IsBusy = false;
Failed = !String.IsNullOrEmpty(Data.Error);
}
/// <summary>
/// Event that is raised when the background work is Started. This event
/// is raised by the internal BackgroundTaskManager<T> component
/// </summary>
private void BackgroundTaskStarted(object sender, EventArgs args)
{
//The order that these properties IS IMPORTANT, as it dictates
//which Adorner will be shown
IsBusy = true;
Failed = false;
}
#endregion
#region Public Methods
/// <summary>
/// Run the work delegate on a new thread
/// </summary>
public void Run()
{
SetupWorker();
bgWorker.RunBackgroundTask();
}
#endregion
#region Public Properties
/// <summary>
/// The actual work delegate. This must ALWAYS take a
/// Dictionary<String,Object> as the 1st parameter, which is the collection
/// of parameters that the work delegate may need to do its work. This can obviously
/// be null. The T is the expected return type for the threading operation
/// </summary>
public Func<Dictionary<String,Object>,ThreadableItem<T>> TaskFunc
{
set
{
taskFunc = value;
}
}
/// <summary>
/// A Dictionary of key/value pairs, where each pair is a parameter
/// that the work delegate (TaskFunc) may need to do its work
/// </summary>
public Dictionary<String, Object> Parameters
{
get { return parameters; }
set { parameters = value; }
}
/// <summary>
/// The BackgroundTaskManager exposed so you can use it within
/// Unit tests. See the actual <see cref="BackgroundTaskManager">
/// BackgroundTaskManager</see> code for how to do that
/// </summary>
public BackgroundTaskManager<ThreadableItem<T>> BgWorker
{
get { return bgWorker; }
}
/// <summary>
/// The actual Data that is the result of running the
/// background threading operation
/// </summary>
public ThreadableItem<T> Data
{
get { return data; }
set
{
data = value;
if (data != null)
this.ErrorMessage = data.Error;
NotifyPropertyChanged("Data");
}
}
#endregion
}
}
|
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 currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)
- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence
Both of these at Sussex University UK.
Award(s)
I am lucky enough to have won a few awards for Zany Crazy code articles over the years
- Microsoft C# MVP 2016
- Codeproject MVP 2016
- Microsoft C# MVP 2015
- Codeproject MVP 2015
- Microsoft C# MVP 2014
- Codeproject MVP 2014
- Microsoft C# MVP 2013
- Codeproject MVP 2013
- Microsoft C# MVP 2012
- Codeproject MVP 2012
- Microsoft C# MVP 2011
- Codeproject MVP 2011
- Microsoft C# MVP 2010
- Codeproject MVP 2010
- Microsoft C# MVP 2009
- Codeproject MVP 2009
- Microsoft C# MVP 2008
- Codeproject MVP 2008
- And numerous codeproject awards which you can see over at my blog