/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text;
using System.Threading;
using Everest.Library;
namespace Everest.Library.Scheduler{
public class JobExecutor : IDisposable
{
NameValueCollection parameter;
IJob job;
EventWaitHandle waitHandler;
RegisteredWaitHandle registeredHandler;
/// <summary>
/// Initializes a new instance of the <see cref="JobExecutor"/> class.
/// </summary>
/// <param name="type">The type.</param>
/// <param name="interval">The interval.</param>
/// <param name="parameter">The parameter.</param>
public JobExecutor(string key, Type type, long interval, NameValueCollection parameter)
{
this.Key = key;
this.parameter = parameter;
job = (IJob)Activator.CreateInstance(type);
this.Interval = interval;
waitHandler = new ManualResetEvent(false);
}
/// <summary>
/// Gets the total count of job run.
/// </summary>
/// <value>The total count.</value>
public int TotalCount { get; private set; }
/// <summary>
/// Gets or sets the key.
/// </summary>
/// <value>The key.</value>
public string Key { get; private set; }
/// <summary>
/// Gets or sets the job.
/// </summary>
/// <value>The job.</value>
public IJob Job { get; private set; }
/// <summary>
/// Gets or sets the interval.
/// </summary>
/// <value>The interval.</value>
public long Interval { get; set; }
/// <summary>
/// Runs this instance.
/// </summary>
public void Run()
{
//Log.Info(string.Format(Resources.StartJob, this.Key, DateTime.Now.ToString()));
DoRun();
}
private void DoRun()
{
//
//onlyOncefalse
// IsCanceledstateIsCanceled
registeredHandler = ThreadPool.RegisterWaitForSingleObject(this.waitHandler, new WaitOrTimerCallback(this.RunJob), this.IsCanceled, Interval, true);
}
/// <summary>
/// Stops this instance.
/// </summary>
public void Stop()
{
Log.Info(string.Format(Resources.StopJob, this.Key, DateTime.Now.ToString(), this.TotalCount));
this.IsCanceled = true;
this.Dispose();
}
/// <summary>
/// Runs the job.
/// </summary>
/// <param name="state">The state.</param>
/// <param name="timedOut">if set to <c>true</c> [timed out].</param>
private void RunJob(object state, bool timedOut)
{
if (this.IsRunning == false)
{
lock (this)
{
if (IsRunning == false)
{
//IsCanceled..
var isCanceled = (bool)state;
if (isCanceled)
{
return;
}
try
{
TotalCount += 1;
//Log.Info(string.Format(Resources.EachTimeRunning, this.Key, DateTime.Now.ToString(), TotalCount));
this.IsRunning = true;
isCanceled = isCanceled || !this.job.Run(parameter);
this.IsRunning = false;
//Log.Info(string.Format(Resources.EachTimeRunFinish, this.Key, DateTime.Now.ToString(), TotalCount));
}
catch (Exception e)
{
Log.Error(e);
}
//continue to run the job.
if (!isCanceled)
{
this.DoRun();
}
}
}
}
}
/// <summary>
/// Gets if the job is on running.
/// </summary>
/// <value>
/// <c>true</c> if this job is running; otherwise, <c>false</c>.
/// </value>
public bool IsRunning { get; private set; }
/// <summary>
/// Gets if the job is canceled.
/// </summary>
/// <value>
/// <c>true</c> if this instance is canceled; otherwise, <c>false</c>.
/// </value>
public bool IsCanceled { get; private set; }
#region IDisposable Members
public void Dispose()
{
this.registeredHandler = null;
//could not to be unregisted.
//if (registeredHandler != null)
//{
// this.registeredHandler.Unregister(waitHandler);
//}
}
#endregion
}
}
|