Skip to content

Instantly share code, notes, and snippets.

@yemrekeskin
Created June 22, 2013 16:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yemrekeskin/5841482 to your computer and use it in GitHub Desktop.
Save yemrekeskin/5841482 to your computer and use it in GitHub Desktop.
Processor class for critical jobs in c#
public interface IProcessor
{
void Process();
}
public abstract class BaseProcessor
: IProcessor
{
public delegate void ProcessorStartingEventHandler(params Object[] param);
public delegate void ProcessorStartedEventHandler(params Object[] param);
public delegate void ProcessorCompletedEventHandler(params Object[] param);
public delegate void ProcessorErrorEventHandler(params Object[] param);
public ProcessorStartingEventHandler ProcessorStarting = null;
public ProcessorStartedEventHandler ProcessorStarted = null;
public ProcessorCompletedEventHandler ProcessorCompleted = null;
public ProcessorErrorEventHandler ProcessorError = null;
// you can set status in the processor class
public ProcessorStatus.Current Status { get; private set; }
// parameter variables
public Parameters _parameters = null;
public Parameters Parameters
{
set { _parameters = value; }
}
// threading mechanism (Semaphore)
private static Semaphore _semaphore = null;
private static object _semaphoreLockObj = new object();
// singleton pattern for semaphore
private void InitializeSemaphore(int jobCountLimit)
{
if (_semaphore == null)
{
lock (_semaphoreLockObj)
{
if (_semaphore == null)
{
_semaphore = new Semaphore(jobCountLimit, jobCountLimit);
}
}
}
}
// ctor methods
public BaseProcessor(Parameters param, int jobCountLimit)
{
this._parameters = param;
InitializeSemaphore(jobCountLimit);
}
public BaseProcessor(Parameters param)
: this(param, 3)
{ }
// Real Job Method
protected abstract void RunJob(object param, out object[] output);
public void Process()
{
// starting loging for real job's log table
this.Status = ProcessorStatus.Current.Starting;
if (ProcessorStarting != null)
ProcessorStarting(this.GetType());
ThreadPool.QueueUserWorkItem(new WaitCallback(Job), this._parameters);
}
private void Job(object param)
{
object[] output = null;
// started loging
this.Status = ProcessorStatus.Current.Started;
if (ProcessorStarted != null)
ProcessorStarted(this.GetType());
try
{
_semaphore.WaitOne();
RunJob(param, out output);
}
catch (Exception ex)
{
this.Status = ProcessorStatus.Current.Error;
if (ProcessorError != null)
{
ProcessorError(this.GetType(), ex);
}
// error logging
}
finally
{
_semaphore.Release();
}
// completing loging
this.Status = ProcessorStatus.Current.Completing;
if (ProcessorCompleted != null)
{
ProcessorCompleted(this.GetType(), output);
}
// completed loging
this.Status = ProcessorStatus.Current.Completed;
}
}
// Customized Processor Class for custom jobs
public class MainProcessor
: BaseProcessor
{
public MainProcessor(Parameters param, int jobLimit)
: base(param, jobLimit)
{ }
public MainProcessor(Parameters param)
: base(param)
{ }
protected override void RunJob(object param, out object[] output)
{
MainJob mj = new MainJob();
output = mj.Start(param as Parameters);
}
}
public class ProcessorStatus
{
public enum Current
{
Starting = 1,
Started = 2,
Completing = 3,
Completed = 4,
Error = 5
}
}
public class Parameters
{
public IDictionary<string, Object> _prms = null;
public Parameters()
{
this._prms = new Dictionary<string, Object>();
}
public void Add(string key, object value)
{
this.Remove(key);
if (!String.IsNullOrEmpty(key))
this._prms.Add(key, value);
}
public void Remove(string key)
{
if (this._prms.ContainsKey(key) && !String.IsNullOrEmpty(key))
this._prms.Remove(key);
}
public object TryGetValue(string key)
{
object obj;
_prms.TryGetValue(key, out obj);
return obj;
}
public void Clear()
{
this._prms.Clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment