//This file is part of ORM.NET.
//
//ORM.NET is free software; you can redistribute it and/or
//modify it under the terms of the GNU Lesser General Public
//License as published by the Free Software Foundation; either
//version 2.1 of the License, or (at your option) any later version.
//
//ORM.NET is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
//Lesser General Public License for more details.
//
//You should have received a copy of the GNU Lesser General Public
//License along with ORM.NET; if not, write to the Free Software
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
using System;
using System.Threading;
using System.Collections;
using System.ComponentModel;
namespace OrmLib{
/// <summary>
/// Inherit from this to create jobs that run as a service, in multiple threads, repeatedly.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
abstract public class Job
{
/// <summary>
/// Unique identifier.
/// </summary>
public Guid JobId = Guid.NewGuid();
/// <summary>
/// Must orerride this, all your code will go here.
/// </summary>
/// <returns>Whether to cal DoJob again.</returns>
abstract public bool DoJob();
}
/// <summary>
/// Runs <seealso cref="Job"/>s
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public class JobHandler
{
private long NumActiveThreads = 0;
private ManualResetEvent ExitEvent = new ManualResetEvent(false);
public ManualResetEvent LastThreadEvent = new ManualResetEvent(false);
private int LoopInterval = 1000;
public JobHandler()
{
LoopInterval = 1000;
}
public JobHandler(int loopInterval)
{
LoopInterval = loopInterval;
}
public void JobCallback( Object state )
{
System.Threading.Interlocked.Increment( ref NumActiveThreads );
do
{
bool bContinue = ((Job)state).DoJob();
if (!bContinue) break;
} while ( !ExitEvent.WaitOne( LoopInterval, false) );
long Count = System.Threading.Interlocked.Decrement( ref NumActiveThreads );
System.Diagnostics.Debug.WriteLine("Thread " + ((Job)state).JobId.ToString() + " quitting");
if (Count == 0) LastThreadEvent.Set();
}
public void AddJob( Job job)
{
ThreadPool.QueueUserWorkItem( new WaitCallback( JobCallback), job);
}
public long ActiveThreadCount
{
get
{
return NumActiveThreads;
}
}
public void WaitJobs()
{
LastThreadEvent.WaitOne( TimeSpan.MaxValue, false );
}
public void StopJobs()
{
ExitEvent.Set();
}
}
}
|