Skip to content

Instantly share code, notes, and snippets.

@goodwill
Created November 10, 2009 06:36
Show Gist options
  • Save goodwill/230679 to your computer and use it in GitHub Desktop.
Save goodwill/230679 to your computer and use it in GitHub Desktop.
using System.Threading;
using System.Collections.Generic;
using System;
namespace AutoLoader.Loader
{
public interface IAutoLoadUnit
{
void Abort();
int CurrentThreadNumber { get; }
void DieNatural();
string Name { get; set; }
AutoLoadUnitMode RunMode { get; set; }
void Start();
AutoLoadUnitStatus Status { get; }
int ThreadCount { get; }
}
public enum AutoLoadUnitStatus
{
Ready,
Started,
Finished,
ToDie,
Abort,
UnExpectedFinish
}
public class AutoLoadUnit : IAutoLoadUnit
{
private object _statusLock = new object();
private object _setAutoLock = new object();
private bool _isSetAutoDie = false;
public AutoLoadUnitStatus Status { get; private set; }
public string Name { get; set; }
public AutoLoadUnitMode RunMode { get; set; }
public int ThreadCount {get;set;}
public int CurrentThreadNumber { get; protected set; }
protected IList<Thread> _threads;
protected int Timer { get; set; }
public AutoLoadUnit()
{
this.RunMode = new AutoLoadUnitMode();
}
protected void Setup()
{
lock (this._statusLock)
{
this.Status = AutoLoadUnitStatus.Ready;
this._threads = new List<Thread>();
this.CurrentThreadNumber = 0;
this.OnSetup();
this.Status = AutoLoadUnitStatus.Started;
}
}
protected void Run()
{
bool isReady = false;
lock (this._statusLock)
{
isReady = object.Equals(AutoLoadUnitStatus.Started, this.Status);
}
if (isReady)
{
this.OnRun();
}
}
protected virtual void OnException(Exception e){}
protected void TearDown()
{
this.OnTearDown();
lock (this._statusLock)
{
if (object.Equals(this.Status, AutoLoadUnitStatus.Started)
|| object.Equals(this.Status, AutoLoadUnitStatus.ToDie))
this.Status = AutoLoadUnitStatus.Finished;
}
}
public void Start()
{
try
{
this.OnStart();
}
catch (Exception e)
{
try
{
this.OnException(e);
}
catch (Exception) { }
finally
{
lock (this._statusLock)
{
this.Status = AutoLoadUnitStatus.UnExpectedFinish;
}
}
}
}
protected void OnStart()
{
lock (this)
{
this.Setup();
for (int i = 0; i < this.ThreadCount; i++)
{
Thread thread = new Thread(new ThreadStart(this.Run));
thread.Start();
this._threads.Add(thread);
this.CurrentThreadNumber++;
//check if abort
bool isDie;
lock (this._statusLock)
{
isDie = (object.Equals(AutoLoadUnitStatus.ToDie, this.Status)
|| object.Equals(AutoLoadUnitStatus.Abort, this.Status)
|| object.Equals(AutoLoadUnitStatus.UnExpectedFinish,this.Status));
}
if (isDie)
break;
TimeSpan span = this.RunMode.GetTimeSpan();
Thread.Sleep(span);
}
while (true)
{
if (!this.CheckThreadsAlive())
break;
else
Thread.Sleep(1000);
}
this.TearDown();
}
}
public void DieNatural()
{
lock (this._statusLock)
{
this.Status = AutoLoadUnitStatus.ToDie;
}
}
public void Abort()
{
lock (this._statusLock)
{
this.Status = AutoLoadUnitStatus.Abort;
}
Thread.CurrentThread.Abort();
}
public bool CheckThreadsAlive()
{
bool isAlive = false;
foreach (Thread thread in this._threads)
{
if (thread.IsAlive)
{
isAlive = true;
break;
}
}
return isAlive;
}
public void SetAutoDieAfter(int milseconds)
{
lock (this._setAutoLock)
{
if (!this._isSetAutoDie)
{
this.Timer = milseconds;
Thread thead = new Thread(new ThreadStart(CreateTimer));
thead.Start();
}
}
}
private void CreateTimer()
{
Thread.Sleep(this.Timer);
this.DieNatural();
}
protected virtual void OnSetup(){}
protected virtual void OnRun(){}
protected virtual void OnTearDown(){}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment