Agregar archivos de proyecto.
This commit is contained in:
18
Baget/UtilidadesTSL4net.c.nuspec
Normal file
18
Baget/UtilidadesTSL4net.c.nuspec
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<package>
|
||||||
|
<metadata>
|
||||||
|
<id>UtilidadesTSL4net.c</id>
|
||||||
|
<version>1.0.0.0</version>
|
||||||
|
<authors>Manuel</authors>
|
||||||
|
<owners>Tecnosis S.A.</owners>
|
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
|
<description>Utilidades c# WPF Tecnosis.</description>
|
||||||
|
<tags>UtilidadesTSL4net.c .net48</tags>
|
||||||
|
<dependencies>
|
||||||
|
<group targetFramework=".NETFramework4.8" />
|
||||||
|
</dependencies>
|
||||||
|
</metadata>
|
||||||
|
<files>
|
||||||
|
<file src="C:\tecnosis.git\Comunes\UtilidadesTSL4net.c\bin\Debug\UtilidadesTSL4net.c.dll" target="lib\net48\" />
|
||||||
|
</files>
|
||||||
|
</package>
|
||||||
BIN
Baget/nuget.exe
Normal file
BIN
Baget/nuget.exe
Normal file
Binary file not shown.
97
EventStorage.cs
Normal file
97
EventStorage.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.XPath;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Null event strorage disables error recovery by returning now for the last time an event fired.
|
||||||
|
/// </summary>
|
||||||
|
public class NullEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public NullEventStorage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
return DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Local event strorage keeps the last time in memory so that skipped events are not recovered.
|
||||||
|
/// </summary>
|
||||||
|
public class LocalEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public LocalEventStorage()
|
||||||
|
{
|
||||||
|
_LastTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
_LastTime = Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
if (_LastTime == DateTime.MaxValue)
|
||||||
|
_LastTime = DateTime.Now;
|
||||||
|
return _LastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime _LastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FileEventStorage saves the last time in an XmlDocument so that recovery will include periods that the
|
||||||
|
/// process is shutdown.
|
||||||
|
/// </summary>
|
||||||
|
public class FileEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public FileEventStorage(string FileName, string XPath)
|
||||||
|
{
|
||||||
|
_FileName = FileName;
|
||||||
|
_XPath = XPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
_Doc.SelectSingleNode(_XPath).Value = Time.ToString();
|
||||||
|
_Doc.Save(_FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
_Doc.Load(_FileName);
|
||||||
|
string Value = _Doc.SelectSingleNode(_XPath).Value;
|
||||||
|
if (Value == null || Value == string.Empty)
|
||||||
|
return DateTime.Now;
|
||||||
|
return DateTime.Parse(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
string _FileName;
|
||||||
|
string _XPath;
|
||||||
|
XmlDocument _Doc = new XmlDocument();
|
||||||
|
}
|
||||||
|
}
|
||||||
45
IScheduledItem.cs
Normal file
45
IScheduledItem.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IScheduledItem represents a scheduled event. You can query it for the number of events that occur
|
||||||
|
/// in a time interval and for the remaining interval before the next event.
|
||||||
|
/// </summary>
|
||||||
|
public interface IScheduledItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the times of the events that occur in the given time interval. The interval is closed
|
||||||
|
/// at the start and open at the end so that intervals can be stacked without overlapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Begin">The beginning of the interval</param>
|
||||||
|
/// <param name="End">The end of the interval</param>
|
||||||
|
/// <returns>All events >= Begin and < End </returns>
|
||||||
|
void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the next run time of the scheduled item. Optionally excludes the starting time.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time of the interval</param>
|
||||||
|
/// <param name="IncludeStartTime">if true then the starting time is included in the query false, it is excluded.</param>
|
||||||
|
/// <returns>The next execution time either on or after the starting time.</returns>
|
||||||
|
DateTime NextRunTime(DateTime time, bool IncludeStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
332
MethodCall.cs
Normal file
332
MethodCall.cs
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IParameterSetter represents a serialized parameter list. This is used to provide a partial specialized
|
||||||
|
/// method call. This is useful for remote invocation of method calls. For example if you have a method with
|
||||||
|
/// 3 parameters. The first 2 might represent static data such as a report and a storage location. The third
|
||||||
|
/// might be the time that the report is invoked, which is only known when the method is invoked. Using this,
|
||||||
|
/// you just pass the method and the first 2 parameters to a timer object, which supplies the 3rd parameter.
|
||||||
|
/// Without these objects, you would have to generate a custom object type for each method you wished to
|
||||||
|
/// execute in this manner and store the static parameters as instance variables.
|
||||||
|
/// </summary>
|
||||||
|
public interface IParameterSetter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This resets the setter to the beginning. It is used for setters that rely on positional state
|
||||||
|
/// information. It is called prior to setting any method values.
|
||||||
|
/// </summary>
|
||||||
|
void reset();
|
||||||
|
/// <summary>
|
||||||
|
/// This method is used to both query support for setting a parameter and actually set the value.
|
||||||
|
/// True is returned if the parameter passed in is updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pi">The reflection information about this parameter.</param>
|
||||||
|
/// <param name="ParameterLoc">The location of the prameter in the parameter list.</param>
|
||||||
|
/// <param name="parameter">The parameter object</param>
|
||||||
|
/// <returns>true if the parameter is matched and false otherwise</returns>
|
||||||
|
bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This setter object takes a simple object array full of parameter data. It applys the objects in order
|
||||||
|
/// to the method parameter list.
|
||||||
|
/// </summary>
|
||||||
|
public class OrderParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
public OrderParameterSetter(params object[] _Params)
|
||||||
|
{
|
||||||
|
_ParamList = _Params;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
_counter = 0;
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
if (_counter >= _ParamList.Length)
|
||||||
|
return false;
|
||||||
|
parameter = _ParamList[_counter++];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object[] _ParamList;
|
||||||
|
int _counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This setter object stores the parameter data in a Hashtable and uses the hashtable keys to match
|
||||||
|
/// the parameter names of the method to the parameter data. This allows methods to be called like
|
||||||
|
/// stored procedures, with the parameters being passed in independent of order.
|
||||||
|
/// </summary>
|
||||||
|
public class NamedParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
public NamedParameterSetter(Hashtable Params)
|
||||||
|
{
|
||||||
|
_Params = Params;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
string ParamName = pi.Name;
|
||||||
|
if (!_Params.ContainsKey(ParamName))
|
||||||
|
return false;
|
||||||
|
parameter = _Params[ParamName];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Hashtable _Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ParameterSetterList maintains a collection of IParameterSetter objects and applies them in order to each
|
||||||
|
/// parameter of the method. Each time a match occurs the next parameter is tried starting with the first
|
||||||
|
/// setter object until it is matched.
|
||||||
|
/// </summary>
|
||||||
|
public class ParameterSetterList
|
||||||
|
{
|
||||||
|
public void Add(IParameterSetter setter)
|
||||||
|
{
|
||||||
|
_List.Add(setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IParameterSetter[] ToArray()
|
||||||
|
{
|
||||||
|
return (IParameterSetter[])_List.ToArray(typeof(IParameterSetter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
foreach(IParameterSetter Setter in _List)
|
||||||
|
Setter.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetParameters(MethodInfo Method)
|
||||||
|
{
|
||||||
|
ParameterInfo[] Params = Method.GetParameters();
|
||||||
|
object[] Values = new object[Params.Length];
|
||||||
|
//TODO: Update to iterate backwards
|
||||||
|
for(int i=0; i<Params.Length; ++i)
|
||||||
|
SetValue(Params[i], i, ref Values[i]);
|
||||||
|
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetParameters(MethodInfo Method, IParameterSetter LastSetter)
|
||||||
|
{
|
||||||
|
ParameterInfo[] Params = Method.GetParameters();
|
||||||
|
object[] Values = new object[Params.Length];
|
||||||
|
//TODO: Update to iterate backwards
|
||||||
|
for(int i=0; i<Params.Length; ++i)
|
||||||
|
{
|
||||||
|
if (!SetValue(Params[i], i, ref Values[i]))
|
||||||
|
LastSetter.GetParameterValue(Params[i], i, ref Values[i]);
|
||||||
|
}
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetValue(ParameterInfo Info, int i, ref object Value)
|
||||||
|
{
|
||||||
|
foreach(IParameterSetter Setter in _List)
|
||||||
|
{
|
||||||
|
if (Setter.GetParameterValue(Info, i, ref Value))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList _List = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IMethodCall represents a partially specified parameter data list and a method. This allows methods to be
|
||||||
|
/// dynamically late invoked for things like timers and other event driven frameworks.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMethodCall
|
||||||
|
{
|
||||||
|
ParameterSetterList ParamList { get; }
|
||||||
|
object Execute();
|
||||||
|
object Execute(IParameterSetter Params);
|
||||||
|
void EventHandler(object obj, EventArgs e);
|
||||||
|
IAsyncResult BeginExecute(AsyncCallback callback, object obj);
|
||||||
|
IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate object Exec();
|
||||||
|
delegate object Exec2(IParameterSetter Params);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method call captures the data required to do a defered method call.
|
||||||
|
/// </summary>
|
||||||
|
public class DelegateMethodCall : MethodCallBase, IMethodCall
|
||||||
|
{
|
||||||
|
public DelegateMethodCall(Delegate f)
|
||||||
|
{
|
||||||
|
_f = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateMethodCall(Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
if (f.Method.GetParameters().Length < Params.Length)
|
||||||
|
throw new ArgumentException("Too many parameters specified for delegate", "f");
|
||||||
|
|
||||||
|
_f = f;
|
||||||
|
ParamList.Add(new OrderParameterSetter(Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateMethodCall(Delegate f, IParameterSetter Params)
|
||||||
|
{
|
||||||
|
_f = f;
|
||||||
|
ParamList.Add(Params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Delegate _f;
|
||||||
|
|
||||||
|
public Delegate f
|
||||||
|
{
|
||||||
|
get { return _f; }
|
||||||
|
set { _f = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodInfo Method
|
||||||
|
{
|
||||||
|
get { return _f.Method; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute()
|
||||||
|
{
|
||||||
|
return f.DynamicInvoke(GetParameterList(Method));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute(IParameterSetter Params)
|
||||||
|
{
|
||||||
|
return f.DynamicInvoke(GetParameterList(Method, Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EventHandler(object obj, EventArgs e)
|
||||||
|
{
|
||||||
|
Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Exec _exec;
|
||||||
|
public IAsyncResult BeginExecute(AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
_exec = new Exec(Execute);
|
||||||
|
return _exec.BeginInvoke(callback, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
Exec2 exec = new Exec2(Execute);
|
||||||
|
return exec.BeginInvoke(Params, callback, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DynamicMethodCall : MethodCallBase, IMethodCall
|
||||||
|
{
|
||||||
|
public DynamicMethodCall(MethodInfo method)
|
||||||
|
{
|
||||||
|
_obj = null;
|
||||||
|
_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicMethodCall(object obj, MethodInfo method)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicMethodCall(object obj, MethodInfo method, IParameterSetter setter)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
_method = method;
|
||||||
|
ParamList.Add(setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
object _obj;
|
||||||
|
MethodInfo _method;
|
||||||
|
|
||||||
|
public MethodInfo Method
|
||||||
|
{
|
||||||
|
get { return _method; }
|
||||||
|
set { _method = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute()
|
||||||
|
{
|
||||||
|
return _method.Invoke(_obj, GetParameterList(Method));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute(IParameterSetter Params)
|
||||||
|
{
|
||||||
|
return _method.Invoke(_obj, GetParameterList(Method, Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EventHandler(object obj, EventArgs e)
|
||||||
|
{
|
||||||
|
Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Exec _exec;
|
||||||
|
public IAsyncResult BeginExecute(AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
_exec = new Exec(Execute);
|
||||||
|
return _exec.BeginInvoke(callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
Exec2 exec = new Exec2(Execute);
|
||||||
|
return exec.BeginInvoke(Params, callback, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is a base class that handles the Parameter list management for the 2 dynamic method call methods.
|
||||||
|
/// </summary>
|
||||||
|
public class MethodCallBase
|
||||||
|
{
|
||||||
|
ParameterSetterList _ParamList = new ParameterSetterList();
|
||||||
|
|
||||||
|
public ParameterSetterList ParamList
|
||||||
|
{
|
||||||
|
get { return _ParamList; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected object[] GetParameterList(MethodInfo Method)
|
||||||
|
{
|
||||||
|
ParamList.reset();
|
||||||
|
object[] Params = ParamList.GetParameters(Method);
|
||||||
|
return Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected object[] GetParameterList(MethodInfo Method, IParameterSetter Params)
|
||||||
|
{
|
||||||
|
ParamList.reset();
|
||||||
|
object[] objParams = ParamList.GetParameters(Method, Params);
|
||||||
|
return objParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
Properties/AssemblyInfo.cs
Normal file
35
Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// La información general sobre un ensamblado se controla mediante el siguiente
|
||||||
|
// conjunto de atributos. Cambie estos atributos para modificar la información
|
||||||
|
// asociada con un ensamblado.
|
||||||
|
[assembly: AssemblyTitle("UtilidadesTSL4net.c")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany(".")]
|
||||||
|
[assembly: AssemblyProduct("UtilidadesTSL4net.c")]
|
||||||
|
[assembly: AssemblyCopyright("© . 2008")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Si establece ComVisible como false hace que los tipos de este ensamblado no sean visibles
|
||||||
|
// a los componentes COM. Si necesita obtener acceso a un tipo en este ensamblado desde
|
||||||
|
// COM, establezca el atributo ComVisible como true en este tipo.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// El siguiente GUID sirve como identificador de la biblioteca de tipos si este proyecto se expone a COM
|
||||||
|
[assembly: Guid("51c70542-3016-463d-8d03-d306aae697f8")]
|
||||||
|
|
||||||
|
// La información de versión de un ensamblado consta de los cuatro valores siguientes:
|
||||||
|
//
|
||||||
|
// Versión principal
|
||||||
|
// Versión secundaria
|
||||||
|
// Número de versión de compilación
|
||||||
|
// Revisión
|
||||||
|
//
|
||||||
|
// Puede especificar todos los valores o puede establecer como valores predeterminados los números de revisión y generación
|
||||||
|
// mediante el asterisco ('*'), como se muestra a continuación:
|
||||||
|
[assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.*")]
|
||||||
26
Properties/Settings.Designer.cs
generated
Normal file
26
Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Este código fue generado por una herramienta.
|
||||||
|
// Versión de runtime:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||||
|
// se vuelve a generar el código.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Utilidadescsharp.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.8.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
Properties/Settings.settings
Normal file
6
Properties/Settings.settings
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
</SettingsFile>
|
||||||
63
ReportTimer.cs
Normal file
63
ReportTimer.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
public class ReportEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ReportEventArgs(DateTime Time, int reportNo) { EventTime = Time; ReportNo = reportNo; }
|
||||||
|
public int ReportNo;
|
||||||
|
public DateTime EventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void ReportEventHandler(object sender, ReportEventArgs e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for ReportTimer.
|
||||||
|
/// </summary>
|
||||||
|
public class ReportTimer : ScheduleTimerBase
|
||||||
|
{
|
||||||
|
public void AddReportEvent(IScheduledItem Schedule, int reportNo)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new Exception("You must set elapsed before adding Events");
|
||||||
|
AddJob(new TimerJob(Schedule, new DelegateMethodCall(Handler, Elapsed, reportNo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAsyncReportEvent(IScheduledItem Schedule, int reportNo)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new Exception("You must set elapsed before adding Events");
|
||||||
|
TimerJob Event = new TimerJob(Schedule, new DelegateMethodCall(Handler, Elapsed, reportNo));
|
||||||
|
Event.SyncronizedEvent = false;
|
||||||
|
AddJob(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event ReportEventHandler Elapsed;
|
||||||
|
|
||||||
|
delegate void ConvertHandler(ReportEventHandler Handler, int ReportNo, object sender, DateTime time);
|
||||||
|
static ConvertHandler Handler = new ConvertHandler(Converter);
|
||||||
|
static void Converter(ReportEventHandler Handler, int ReportNo, object sender, DateTime time)
|
||||||
|
{
|
||||||
|
if (Handler == null)
|
||||||
|
throw new ArgumentNullException("Handler");
|
||||||
|
if (sender == null)
|
||||||
|
throw new ArgumentNullException("sender");
|
||||||
|
Handler(sender, new ReportEventArgs(time, ReportNo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
ScheduleFilter.cs
Normal file
75
ScheduleFilter.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is an empty filter that does not filter any of the events.
|
||||||
|
/// </summary>
|
||||||
|
public class Filter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Empty = new Filter();
|
||||||
|
private Filter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This causes only the first event of the interval to be counted.
|
||||||
|
/// </summary>
|
||||||
|
public class FirstEventFilter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Filter = new FirstEventFilter();
|
||||||
|
private FirstEventFilter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
if (List.Count < 2)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
List.RemoveRange(1, List.Count-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This causes only the last event of the interval to be counted.
|
||||||
|
/// </summary>
|
||||||
|
public class LastEventFilter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Filter = new LastEventFilter();
|
||||||
|
private LastEventFilter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
if (List.Count < 2)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
List.RemoveRange(0, List.Count-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
254
ScheduleTimer.cs
Normal file
254
ScheduleTimer.cs
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ScheduleTimer represents a timer that fires on a more human friendly schedule. For example it is easy to
|
||||||
|
/// set it to fire every day at 6:00PM. It is useful for batch jobs or alarms that might be difficult to
|
||||||
|
/// schedule with the native .net timers.
|
||||||
|
/// It is similar to the .net timer that it is based on with the start and stop methods functioning similarly.
|
||||||
|
/// The main difference is the event uses a different delegate and arguement since the .net timer argument
|
||||||
|
/// class is not creatable.
|
||||||
|
/// </summary>
|
||||||
|
public class ScheduleTimerBase : IDisposable
|
||||||
|
{
|
||||||
|
public ScheduleTimerBase()
|
||||||
|
{
|
||||||
|
_Timer = new Timer();
|
||||||
|
_Timer.AutoReset = false;
|
||||||
|
_Timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
|
||||||
|
_Jobs = new TimerJobList();
|
||||||
|
_LastTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer. This method passes in a delegate and the parameters similar to the Invoke method of windows forms.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule that this delegate is to be run on.</param>
|
||||||
|
/// <param name="f">The delegate to run</param>
|
||||||
|
/// <param name="Params">The method parameters to pass if you leave any DateTime parameters unbound, then they will be set with the scheduled run time of the
|
||||||
|
/// method. Any unbound object parameters will get this Job object passed in.</param>
|
||||||
|
public void AddJob(IScheduledItem Schedule, Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
_Jobs.Add(new TimerJob(Schedule, new DelegateMethodCall(f, Params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer to operate asyncronously.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule that this delegate is to be run on.</param>
|
||||||
|
/// <param name="f">The delegate to run</param>
|
||||||
|
/// <param name="Params">The method parameters to pass if you leave any DateTime parameters unbound, then they will be set with the scheduled run time of the
|
||||||
|
/// method. Any unbound object parameters will get this Job object passed in.</param>
|
||||||
|
public void AddAsyncJob(IScheduledItem Schedule, Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
TimerJob Event = new TimerJob(Schedule, new DelegateMethodCall(f, Params));
|
||||||
|
Event.SyncronizedEvent = false;
|
||||||
|
_Jobs.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Event"></param>
|
||||||
|
public void AddJob(TimerJob Event)
|
||||||
|
{
|
||||||
|
_Jobs.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears out all scheduled jobs.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearJobs()
|
||||||
|
{
|
||||||
|
_Jobs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begins executing all assigned jobs at the scheduled times
|
||||||
|
/// </summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_StopFlag = false;
|
||||||
|
QueueNextTime(EventStorage.ReadLastTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Halts executing all jobs. When the timer is restarted all jobs that would have run while the timer was stopped are re-tried.
|
||||||
|
/// </summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_StopFlag = true;
|
||||||
|
_Timer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EventStorage determines the method used to store the last event fire time. It defaults to keeping it in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IEventStorage EventStorage = new LocalEventStorage();
|
||||||
|
public event ExceptionEventHandler Error;
|
||||||
|
|
||||||
|
#region Private Methods and Fields
|
||||||
|
/// <summary>
|
||||||
|
/// This is here to enhance accuracy. Even if nothing is scheduled the timer sleeps for a maximum of 1 minute.
|
||||||
|
/// </summary>
|
||||||
|
private static TimeSpan MAX_INTERVAL = new TimeSpan(0, 1, 0);
|
||||||
|
|
||||||
|
private DateTime _LastTime;
|
||||||
|
private Timer _Timer;
|
||||||
|
private TimerJobList _Jobs;
|
||||||
|
private volatile bool _StopFlag;
|
||||||
|
|
||||||
|
private double NextInterval(DateTime thisTime)
|
||||||
|
{
|
||||||
|
TimeSpan interval = _Jobs.NextRunTime(thisTime)-thisTime;
|
||||||
|
if (interval > MAX_INTERVAL)
|
||||||
|
interval = MAX_INTERVAL;
|
||||||
|
//Handles the case of 0 wait time, the interval property requires a duration > 0.
|
||||||
|
return (interval.TotalMilliseconds == 0) ? 1 : interval.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void QueueNextTime(DateTime thisTime)
|
||||||
|
{
|
||||||
|
_Timer.Interval = NextInterval(thisTime);
|
||||||
|
System.Diagnostics.Debug.WriteLine(_Timer.Interval);
|
||||||
|
_LastTime = thisTime;
|
||||||
|
EventStorage.RecordLastTime(thisTime);
|
||||||
|
_Timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_Jobs == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_Timer.Stop();
|
||||||
|
|
||||||
|
foreach(TimerJob Event in _Jobs.Jobs)
|
||||||
|
{
|
||||||
|
try { Event.Execute(this, _LastTime, e.SignalTime, Error); }
|
||||||
|
catch (Exception ex) { OnError(DateTime.Now, Event, ex); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnError(DateTime.Now, null, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_StopFlag == false)
|
||||||
|
QueueNextTime(e.SignalTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnError(DateTime eventTime, TimerJob job, Exception e)
|
||||||
|
{
|
||||||
|
if (Error == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try { Error(this, new ExceptionEventArgs(eventTime, e)); }
|
||||||
|
catch (Exception) {}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_Timer != null)
|
||||||
|
_Timer.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ScheduleTimer : ScheduleTimerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add event is used in conjunction with the Elaspsed event handler. Set the Elapsed handler, add your schedule and call start.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule to fire the event at. Adding additional schedules will cause the event to fire whenever either schedule calls for it.</param>
|
||||||
|
public void AddEvent(IScheduledItem Schedule)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new ArgumentNullException("Elapsed", "member variable is null.");
|
||||||
|
|
||||||
|
AddJob(new TimerJob(Schedule, new DelegateMethodCall(Elapsed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The event to fire when you only need to fire one event.
|
||||||
|
/// </summary>
|
||||||
|
public event ScheduledEventHandler Elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ExceptionEventArgs allows exceptions to be captured and sent to the OnError event of the timer.
|
||||||
|
/// </summary>
|
||||||
|
public class ExceptionEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ExceptionEventArgs(DateTime eventTime, Exception e)
|
||||||
|
{
|
||||||
|
EventTime = eventTime;
|
||||||
|
Error = e;
|
||||||
|
}
|
||||||
|
public DateTime EventTime;
|
||||||
|
public Exception Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ExceptionEventHandler is the method type used by the OnError event for the timer.
|
||||||
|
/// </summary>
|
||||||
|
public delegate void ExceptionEventHandler(object sender, ExceptionEventArgs Args);
|
||||||
|
|
||||||
|
public class ScheduledEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ScheduledEventArgs(DateTime eventTime)
|
||||||
|
{
|
||||||
|
EventTime = eventTime;
|
||||||
|
}
|
||||||
|
public DateTime EventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void ScheduledEventHandler(object sender, ScheduledEventArgs e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IResultFilter interface represents filters that either sort the events for an interval or
|
||||||
|
/// remove duplicate events either selecting the first or the last event.
|
||||||
|
/// </summary>
|
||||||
|
public interface IResultFilter
|
||||||
|
{
|
||||||
|
void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IEventStorage is used to provide persistance of schedule during service shutdowns.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEventStorage
|
||||||
|
{
|
||||||
|
void RecordLastTime(DateTime Time);
|
||||||
|
DateTime ReadLastTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
80
ScheduledItems/BlockWrapper.cs
Normal file
80
ScheduledItems/BlockWrapper.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class will be used to implement a filter that enables a window of activity. For cases where you want to
|
||||||
|
/// run every 15 minutes between 6:00 AM and 5:00 PM. Or just on weekdays or weekends.
|
||||||
|
/// </summary>
|
||||||
|
public class BlockWrapper : IScheduledItem
|
||||||
|
{
|
||||||
|
public BlockWrapper(IScheduledItem item, string StrBase, string BeginOffset, string EndOffset)
|
||||||
|
{
|
||||||
|
_Item = item;
|
||||||
|
_Begin = new ScheduledTime(StrBase, BeginOffset);
|
||||||
|
_End = new ScheduledTime(StrBase, EndOffset);
|
||||||
|
}
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = NextRunTime(Next, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
return NextRunTime(time, 100, AllowExact);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime NextRunTime(DateTime time, int count, bool AllowExact)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
throw new Exception("Invalid block wrapper combination.");
|
||||||
|
|
||||||
|
DateTime
|
||||||
|
temp = _Item.NextRunTime(time, AllowExact),
|
||||||
|
begin = _Begin.NextRunTime(time, true),
|
||||||
|
end = _End.NextRunTime(time, true);
|
||||||
|
System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2} {3}", time, begin, end, temp));
|
||||||
|
bool A = temp > end, B = temp < begin, C = end < begin;
|
||||||
|
System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2}", A, B, C));
|
||||||
|
if (C)
|
||||||
|
{
|
||||||
|
if (A && B)
|
||||||
|
return NextRunTime(begin, --count, false);
|
||||||
|
else
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!A && !B)
|
||||||
|
return temp;
|
||||||
|
if (!A)
|
||||||
|
return NextRunTime(begin, --count, false);
|
||||||
|
else
|
||||||
|
return NextRunTime(end, --count, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private IScheduledItem _Item;
|
||||||
|
private ScheduledTime _Begin, _End;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
ScheduledItems/EventInstance.cs
Normal file
52
ScheduledItems/EventInstance.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// There have been quite a few requests to allow scheduling of multiple delegates and method parameter data
|
||||||
|
/// from the same timer. This class allows you to match the event with the time that it fired. I want to keep
|
||||||
|
/// the same simple implementation of the EventQueue and interval classes since they can be reused elsewhere.
|
||||||
|
/// The timer should be responsible for matching this data up.
|
||||||
|
/// </summary>
|
||||||
|
public class EventInstance : IComparable
|
||||||
|
{
|
||||||
|
public EventInstance(DateTime time, IScheduledItem scheduleItem, object data)
|
||||||
|
{
|
||||||
|
Time = time;
|
||||||
|
ScheduleItem = scheduleItem;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
public DateTime Time;
|
||||||
|
public IScheduledItem ScheduleItem;
|
||||||
|
public object Data;
|
||||||
|
|
||||||
|
public int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (obj is EventInstance)
|
||||||
|
return Time.CompareTo(((EventInstance)obj).Time);
|
||||||
|
if (obj is DateTime)
|
||||||
|
return Time.CompareTo((DateTime)obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
81
ScheduledItems/EventQueue.cs
Normal file
81
ScheduledItems/EventQueue.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The event queue is a collection of scheduled items that represents the union of all child scheduled items.
|
||||||
|
/// This is useful for events that occur every 10 minutes or at multiple intervals not covered by the simple
|
||||||
|
/// scheduled items.
|
||||||
|
/// </summary>
|
||||||
|
public class EventQueue : IScheduledItem
|
||||||
|
{
|
||||||
|
public EventQueue()
|
||||||
|
{
|
||||||
|
_List = new ArrayList();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a ScheduledTime to the queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The scheduled time to add</param>
|
||||||
|
public void Add(IScheduledItem time)
|
||||||
|
{
|
||||||
|
_List.Add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the list of scheduled times.
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_List.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the running time for all events in the list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Begin">The beginning time of the interval</param>
|
||||||
|
/// <param name="End">The end time of the interval</param>
|
||||||
|
/// <param name="List">The list to add times to.</param>
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
foreach(IScheduledItem st in _List)
|
||||||
|
st.AddEventsInInterval(Begin, End, List);
|
||||||
|
List.Sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the first time after the starting time for all events in the list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time.</param>
|
||||||
|
/// <param name="AllowExact">If this is true then it allows the return time to match the time parameter, false forces the return time to be greater then the time parameter</param>
|
||||||
|
/// <returns>Either the next event after the input time or greater or equal to depending on the AllowExact parameter.</returns>
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime next = DateTime.MaxValue;
|
||||||
|
//Get minimum datetime from the list.
|
||||||
|
foreach(IScheduledItem st in _List)
|
||||||
|
{
|
||||||
|
DateTime Proposed = st.NextRunTime(time, AllowExact);
|
||||||
|
next = (Proposed < next) ? Proposed : next;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
private ArrayList _List;
|
||||||
|
}
|
||||||
|
}
|
||||||
177
ScheduledItems/ScheduledTime.cs
Normal file
177
ScheduledItems/ScheduledTime.cs
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
public enum EventTimeBase
|
||||||
|
{
|
||||||
|
BySecond = 1,
|
||||||
|
ByMinute = 2,
|
||||||
|
Hourly = 3,
|
||||||
|
Daily = 4,
|
||||||
|
Weekly = 5,
|
||||||
|
Monthly = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a simple schedule. It can represent a repeating event that occurs anywhere from every
|
||||||
|
/// second to once a month. It consists of an enumeration to mark the interval and an offset from that interval.
|
||||||
|
/// For example new ScheduledTime(Hourly, new TimeSpan(0, 15, 0)) would represent an event that fired 15 minutes
|
||||||
|
/// after the hour every hour.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class ScheduledTime : IScheduledItem
|
||||||
|
{
|
||||||
|
public ScheduledTime(EventTimeBase Base, TimeSpan Offset)
|
||||||
|
{
|
||||||
|
_Base = Base;
|
||||||
|
_Offset = Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// intializes a simple scheduled time element from a pair of strings.
|
||||||
|
/// Here are the supported formats
|
||||||
|
///
|
||||||
|
/// BySecond - single integer representing the offset in ms
|
||||||
|
/// ByMinute - A comma seperate list of integers representing the number of seconds and ms
|
||||||
|
/// Hourly - A comma seperated list of integers representing the number of minutes, seconds and ms
|
||||||
|
/// Daily - A time in HH:mm:ss AM/PM format
|
||||||
|
/// Weekly - n, time where n represents an integer and time is a time in the Daily format
|
||||||
|
/// Monthly - the same format as weekly.
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="StrBase">A string representing the base enumeration for the scheduled time</param>
|
||||||
|
/// <param name="StrOffset">A string representing the offset for the time.</param>
|
||||||
|
public ScheduledTime(string StrBase, string StrOffset)
|
||||||
|
{
|
||||||
|
//TODO:Create an IScheduled time factory method.
|
||||||
|
_Base = (EventTimeBase)Enum.Parse(typeof(EventTimeBase), StrBase, true);
|
||||||
|
Init(StrOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ArrayAccess(string[] Arr, int i)
|
||||||
|
{
|
||||||
|
if (i >= Arr.Length)
|
||||||
|
return 0;
|
||||||
|
return int.Parse(Arr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = IncInterval(Next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime NextRun = LastSyncForTime(time) + _Offset;
|
||||||
|
if (NextRun == time && AllowExact)
|
||||||
|
return time;
|
||||||
|
if (NextRun > time)
|
||||||
|
return NextRun;
|
||||||
|
return IncInterval(NextRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DateTime LastSyncForTime(DateTime time)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second);
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, 0);
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, 0, 0);
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day);
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
return (new DateTime(time.Year, time.Month, time.Day)).AddDays(-(int)time.DayOfWeek);
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
return new DateTime(time.Year, time.Month, 1);
|
||||||
|
}
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime IncInterval(DateTime Last)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
return Last.AddSeconds(1);
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
return Last.AddMinutes(1);
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
return Last.AddHours(1);
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
return Last.AddDays(1);
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
return Last.AddDays(7);
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
return Last.AddMonths(1);
|
||||||
|
}
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init(string StrOffset)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
_Offset = new TimeSpan(0, 0, 0, 0, int.Parse(StrOffset));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
string[] ArrMinute = StrOffset.Split(',');
|
||||||
|
_Offset = new TimeSpan(0, 0, 0, ArrayAccess(ArrMinute, 0), ArrayAccess(ArrMinute, 1));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
string[] ArrHour = StrOffset.Split(',');
|
||||||
|
_Offset = new TimeSpan(0, 0, ArrayAccess(ArrHour, 0), ArrayAccess(ArrHour, 1), ArrayAccess(ArrHour, 2));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
DateTime Daytime = DateTime.Parse(StrOffset);
|
||||||
|
_Offset = new TimeSpan(0, Daytime.Hour, Daytime.Minute, Daytime.Second, Daytime.Millisecond);
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
string[] ArrWeek = StrOffset.Split(',');
|
||||||
|
if (ArrWeek.Length != 2)
|
||||||
|
throw new Exception("Weekly offset must be in the format n, time where n is the day of the week starting with 0 for sunday");
|
||||||
|
DateTime WeekTime = DateTime.Parse(ArrWeek[1]);
|
||||||
|
_Offset = new TimeSpan(int.Parse(ArrWeek[0]), WeekTime.Hour, WeekTime.Minute, WeekTime.Second, WeekTime.Millisecond);
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
string[] ArrMonth = StrOffset.Split(',');
|
||||||
|
if (ArrMonth.Length != 2)
|
||||||
|
throw new Exception("Monthly offset must be in the format n, time where n is the day of the month starting with 1 for the first day of the month.");
|
||||||
|
DateTime MonthTime = DateTime.Parse(ArrMonth[1]);
|
||||||
|
_Offset = new TimeSpan(int.Parse(ArrMonth[0])-1, MonthTime.Hour, MonthTime.Minute, MonthTime.Second, MonthTime.Millisecond);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventTimeBase _Base;
|
||||||
|
private TimeSpan _Offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
ScheduledItems/SimpleInterval.cs
Normal file
90
ScheduledItems/SimpleInterval.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The simple interval represents the simple scheduling that .net supports natively. It consists of a start
|
||||||
|
/// absolute time and an interval that is counted off from the start time.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class SimpleInterval : IScheduledItem
|
||||||
|
{
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval, int count)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = StartTime + TimeSpan.FromTicks(Interval.Ticks*count);
|
||||||
|
}
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval, DateTime EndTime)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = EndTime;
|
||||||
|
}
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (End <= _StartTime)
|
||||||
|
return;
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = NextRunTime(Next, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime returnTime = NextRunTimeInt(time, AllowExact);
|
||||||
|
Debug.WriteLine(time);
|
||||||
|
Debug.WriteLine(returnTime);
|
||||||
|
Debug.WriteLine(_EndTime);
|
||||||
|
return (returnTime >= _EndTime) ? DateTime.MaxValue : returnTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime NextRunTimeInt(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
TimeSpan Span = time-_StartTime;
|
||||||
|
if (Span < TimeSpan.Zero)
|
||||||
|
return _StartTime;
|
||||||
|
if (ExactMatch(time))
|
||||||
|
return AllowExact ? time : time + _Interval;
|
||||||
|
uint msRemaining = (uint)(_Interval.TotalMilliseconds - ((uint)Span.TotalMilliseconds % (uint)_Interval.TotalMilliseconds));
|
||||||
|
return time.AddMilliseconds(msRemaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ExactMatch(DateTime time)
|
||||||
|
{
|
||||||
|
TimeSpan Span = time-_StartTime;
|
||||||
|
if (Span < TimeSpan.Zero)
|
||||||
|
return false;
|
||||||
|
return (Span.TotalMilliseconds % _Interval.TotalMilliseconds) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeSpan _Interval;
|
||||||
|
private DateTime _StartTime;
|
||||||
|
private DateTime _EndTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
ScheduledItems/SingleEvent.cs
Normal file
45
ScheduledItems/SingleEvent.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>Single event represents an event which only fires once.</summary>
|
||||||
|
public class SingleEvent : IScheduledItem
|
||||||
|
{
|
||||||
|
public SingleEvent(DateTime eventTime)
|
||||||
|
{
|
||||||
|
_EventTime = eventTime;
|
||||||
|
}
|
||||||
|
#region IScheduledItem Members
|
||||||
|
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, System.Collections.ArrayList List)
|
||||||
|
{
|
||||||
|
if (Begin <= _EventTime && End > _EventTime)
|
||||||
|
List.Add(_EventTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool IncludeStartTime)
|
||||||
|
{
|
||||||
|
if (IncludeStartTime)
|
||||||
|
return (_EventTime >= time) ? _EventTime : DateTime.MaxValue;
|
||||||
|
else
|
||||||
|
return (_EventTime > time) ? _EventTime : DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
private DateTime _EventTime;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
181
TimerJob.cs
Normal file
181
TimerJob.cs
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Timer job groups a schedule, syncronization data, a result filter, method information and an enabled state so that multiple jobs
|
||||||
|
/// can be managed by the same timer. Each one operating independently of the others with different syncronization and recovery settings.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerJob
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public TimerJob(IScheduledItem schedule, IMethodCall method)
|
||||||
|
{
|
||||||
|
Schedule = schedule;
|
||||||
|
Method = method;
|
||||||
|
_ExecuteHandler = new ExecuteHandler(ExecuteInternal);
|
||||||
|
}
|
||||||
|
public IScheduledItem Schedule;
|
||||||
|
public bool SyncronizedEvent = true;
|
||||||
|
public IResultFilter Filter;
|
||||||
|
public IMethodCall Method;
|
||||||
|
// public IJobLog Log;
|
||||||
|
public bool Enabled = true;
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool IncludeStartTime)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return DateTime.MaxValue;
|
||||||
|
return Schedule.NextRunTime(time, IncludeStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(object sender, DateTime Begin, DateTime End, ExceptionEventHandler Error)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ArrayList EventList = new ArrayList();
|
||||||
|
Schedule.AddEventsInInterval(Begin, End, EventList);
|
||||||
|
|
||||||
|
if (Filter != null)
|
||||||
|
Filter.FilterResultsInInterval(Begin, End, EventList);
|
||||||
|
|
||||||
|
foreach(DateTime EventTime in EventList)
|
||||||
|
{
|
||||||
|
if (SyncronizedEvent)
|
||||||
|
_ExecuteHandler(sender, EventTime, Error);
|
||||||
|
else
|
||||||
|
_ExecuteHandler.BeginInvoke(sender, EventTime, Error, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteInternal(object sender, DateTime EventTime, ExceptionEventHandler Error)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TimerParameterSetter Setter = new TimerParameterSetter(EventTime, sender);
|
||||||
|
Method.Execute(Setter);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (Error != null)
|
||||||
|
try { Error(this, new ExceptionEventArgs(EventTime, ex)); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void ExecuteHandler(object sender, DateTime EventTime, ExceptionEventHandler Error);
|
||||||
|
|
||||||
|
private ExecuteHandler _ExecuteHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Timer job manages a group of timer jobs.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerJobList
|
||||||
|
{
|
||||||
|
public TimerJobList()
|
||||||
|
{
|
||||||
|
_List = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(TimerJob Event)
|
||||||
|
{
|
||||||
|
_List.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_List.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the next time any of the jobs in the list will run. Allows matching the exact start time. If no matches are found the return
|
||||||
|
/// is DateTime.MaxValue;
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time for the interval being queried. This time is included in the interval</param>
|
||||||
|
/// <returns>The first absolute date one of the jobs will execute on. If none of the jobs needs to run DateTime.MaxValue is returned.</returns>
|
||||||
|
public DateTime NextRunTime(DateTime time)
|
||||||
|
{
|
||||||
|
DateTime next = DateTime.MaxValue;
|
||||||
|
//Get minimum datetime from the list.
|
||||||
|
foreach(TimerJob Job in _List)
|
||||||
|
{
|
||||||
|
DateTime Proposed = Job.NextRunTime(time, true);
|
||||||
|
next = (Proposed < next) ? Proposed : next;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimerJob[] Jobs
|
||||||
|
{
|
||||||
|
get { return (TimerJob[])_List.ToArray(typeof(TimerJob)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList _List;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The timer job allows delegates to be specified with unbound parameters. This ParameterSetter assigns all unbound datetime parameters
|
||||||
|
/// with the specified time and all unbound object parameters with the calling object.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initalize the ParameterSetter with the time to pass to unbound time parameters and object to pass to unbound object parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The time to pass to the unbound DateTime parameters</param>
|
||||||
|
/// <param name="sender">The object to pass to the unbound object parameters</param>
|
||||||
|
public TimerParameterSetter(DateTime time, object sender)
|
||||||
|
{
|
||||||
|
_time = time;
|
||||||
|
_sender = sender;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
switch(pi.ParameterType.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "datetime":
|
||||||
|
parameter = _time;
|
||||||
|
return true;
|
||||||
|
case "object":
|
||||||
|
parameter = _sender;
|
||||||
|
return true;
|
||||||
|
case "scheduledeventargs":
|
||||||
|
parameter = new ScheduledEventArgs(_time);
|
||||||
|
return true;
|
||||||
|
case "eventargs":
|
||||||
|
parameter = new ScheduledEventArgs(_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DateTime _time;
|
||||||
|
object _sender;
|
||||||
|
}
|
||||||
|
}
|
||||||
143
UtilidadesTSL4net.c.csproj
Normal file
143
UtilidadesTSL4net.c.csproj
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>9.0.30729</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{BF2447F5-65A1-4A47-A16E-F2227634E050}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Utilidadescsharp</RootNamespace>
|
||||||
|
<AssemblyName>UtilidadesTSL4net.c</AssemblyName>
|
||||||
|
<FileUpgradeFlags>
|
||||||
|
</FileUpgradeFlags>
|
||||||
|
<OldToolsVersion>3.5</OldToolsVersion>
|
||||||
|
<UpgradeBackupLocation>
|
||||||
|
</UpgradeBackupLocation>
|
||||||
|
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
<SccProjectName>SAK</SccProjectName>
|
||||||
|
<SccLocalPath>SAK</SccLocalPath>
|
||||||
|
<SccAuxPath>SAK</SccAuxPath>
|
||||||
|
<SccProvider>SAK</SccProvider>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="EventStorage.cs" />
|
||||||
|
<Compile Include="IScheduledItem.cs" />
|
||||||
|
<Compile Include="MethodCall.cs" />
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ReportTimer.cs" />
|
||||||
|
<Compile Include="ScheduledItems\BlockWrapper.cs" />
|
||||||
|
<Compile Include="ScheduledItems\EventInstance.cs" />
|
||||||
|
<Compile Include="ScheduledItems\EventQueue.cs" />
|
||||||
|
<Compile Include="ScheduledItems\ScheduledTime.cs" />
|
||||||
|
<Compile Include="ScheduledItems\SimpleInterval.cs" />
|
||||||
|
<Compile Include="ScheduledItems\SingleEvent.cs" />
|
||||||
|
<Compile Include="ScheduleFilter.cs" />
|
||||||
|
<Compile Include="ScheduleTimer.cs" />
|
||||||
|
<Compile Include="TimerJob.cs" />
|
||||||
|
<Compile Include="ucImagen.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="ucImagen.resx">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<DependentUpon>ucImagen.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Baget\UtilidadesTSL4net.c.1.0.0.nupkg" />
|
||||||
|
<None Include="Baget\UtilidadesTSL4net.c.nuspec" />
|
||||||
|
<None Include="bin\Debug\UtilidadesTSL4net.c.1.0.0.nupkg" />
|
||||||
|
<None Include="bin\UtilidadesTSL4net.c.1.0.0.nupkg" />
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Windows Installer 3.1</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Baget\nuget.exe" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
25
UtilidadesTSL4net.c.sln
Normal file
25
UtilidadesTSL4net.c.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 18
|
||||||
|
VisualStudioVersion = 18.6.11806.211 stable
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UtilidadesTSL4net.c", "UtilidadesTSL4net.c.csproj", "{BF2447F5-65A1-4A47-A16E-F2227634E050}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{BF2447F5-65A1-4A47-A16E-F2227634E050}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{BF2447F5-65A1-4A47-A16E-F2227634E050}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BF2447F5-65A1-4A47-A16E-F2227634E050}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{BF2447F5-65A1-4A47-A16E-F2227634E050}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {7AC260D0-FB99-4CCE-9185-C8A31FF3F375}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
97
UtilidadesTSL4net.c/EventStorage.cs
Normal file
97
UtilidadesTSL4net.c/EventStorage.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Xml;
|
||||||
|
using System.Xml.XPath;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Null event strorage disables error recovery by returning now for the last time an event fired.
|
||||||
|
/// </summary>
|
||||||
|
public class NullEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public NullEventStorage()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
return DateTime.Now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Local event strorage keeps the last time in memory so that skipped events are not recovered.
|
||||||
|
/// </summary>
|
||||||
|
public class LocalEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public LocalEventStorage()
|
||||||
|
{
|
||||||
|
_LastTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
_LastTime = Time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
if (_LastTime == DateTime.MaxValue)
|
||||||
|
_LastTime = DateTime.Now;
|
||||||
|
return _LastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime _LastTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// FileEventStorage saves the last time in an XmlDocument so that recovery will include periods that the
|
||||||
|
/// process is shutdown.
|
||||||
|
/// </summary>
|
||||||
|
public class FileEventStorage : IEventStorage
|
||||||
|
{
|
||||||
|
public FileEventStorage(string FileName, string XPath)
|
||||||
|
{
|
||||||
|
_FileName = FileName;
|
||||||
|
_XPath = XPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordLastTime(DateTime Time)
|
||||||
|
{
|
||||||
|
_Doc.SelectSingleNode(_XPath).Value = Time.ToString();
|
||||||
|
_Doc.Save(_FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime ReadLastTime()
|
||||||
|
{
|
||||||
|
_Doc.Load(_FileName);
|
||||||
|
string Value = _Doc.SelectSingleNode(_XPath).Value;
|
||||||
|
if (Value == null || Value == string.Empty)
|
||||||
|
return DateTime.Now;
|
||||||
|
return DateTime.Parse(Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
string _FileName;
|
||||||
|
string _XPath;
|
||||||
|
XmlDocument _Doc = new XmlDocument();
|
||||||
|
}
|
||||||
|
}
|
||||||
45
UtilidadesTSL4net.c/IScheduledItem.cs
Normal file
45
UtilidadesTSL4net.c/IScheduledItem.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IScheduledItem represents a scheduled event. You can query it for the number of events that occur
|
||||||
|
/// in a time interval and for the remaining interval before the next event.
|
||||||
|
/// </summary>
|
||||||
|
public interface IScheduledItem
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the times of the events that occur in the given time interval. The interval is closed
|
||||||
|
/// at the start and open at the end so that intervals can be stacked without overlapping.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Begin">The beginning of the interval</param>
|
||||||
|
/// <param name="End">The end of the interval</param>
|
||||||
|
/// <returns>All events >= Begin and < End </returns>
|
||||||
|
void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the next run time of the scheduled item. Optionally excludes the starting time.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time of the interval</param>
|
||||||
|
/// <param name="IncludeStartTime">if true then the starting time is included in the query false, it is excluded.</param>
|
||||||
|
/// <returns>The next execution time either on or after the starting time.</returns>
|
||||||
|
DateTime NextRunTime(DateTime time, bool IncludeStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
332
UtilidadesTSL4net.c/MethodCall.cs
Normal file
332
UtilidadesTSL4net.c/MethodCall.cs
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// IParameterSetter represents a serialized parameter list. This is used to provide a partial specialized
|
||||||
|
/// method call. This is useful for remote invocation of method calls. For example if you have a method with
|
||||||
|
/// 3 parameters. The first 2 might represent static data such as a report and a storage location. The third
|
||||||
|
/// might be the time that the report is invoked, which is only known when the method is invoked. Using this,
|
||||||
|
/// you just pass the method and the first 2 parameters to a timer object, which supplies the 3rd parameter.
|
||||||
|
/// Without these objects, you would have to generate a custom object type for each method you wished to
|
||||||
|
/// execute in this manner and store the static parameters as instance variables.
|
||||||
|
/// </summary>
|
||||||
|
public interface IParameterSetter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This resets the setter to the beginning. It is used for setters that rely on positional state
|
||||||
|
/// information. It is called prior to setting any method values.
|
||||||
|
/// </summary>
|
||||||
|
void reset();
|
||||||
|
/// <summary>
|
||||||
|
/// This method is used to both query support for setting a parameter and actually set the value.
|
||||||
|
/// True is returned if the parameter passed in is updated.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pi">The reflection information about this parameter.</param>
|
||||||
|
/// <param name="ParameterLoc">The location of the prameter in the parameter list.</param>
|
||||||
|
/// <param name="parameter">The parameter object</param>
|
||||||
|
/// <returns>true if the parameter is matched and false otherwise</returns>
|
||||||
|
bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This setter object takes a simple object array full of parameter data. It applys the objects in order
|
||||||
|
/// to the method parameter list.
|
||||||
|
/// </summary>
|
||||||
|
public class OrderParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
public OrderParameterSetter(params object[] _Params)
|
||||||
|
{
|
||||||
|
_ParamList = _Params;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
_counter = 0;
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
if (_counter >= _ParamList.Length)
|
||||||
|
return false;
|
||||||
|
parameter = _ParamList[_counter++];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
object[] _ParamList;
|
||||||
|
int _counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This setter object stores the parameter data in a Hashtable and uses the hashtable keys to match
|
||||||
|
/// the parameter names of the method to the parameter data. This allows methods to be called like
|
||||||
|
/// stored procedures, with the parameters being passed in independent of order.
|
||||||
|
/// </summary>
|
||||||
|
public class NamedParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
public NamedParameterSetter(Hashtable Params)
|
||||||
|
{
|
||||||
|
_Params = Params;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
string ParamName = pi.Name;
|
||||||
|
if (!_Params.ContainsKey(ParamName))
|
||||||
|
return false;
|
||||||
|
parameter = _Params[ParamName];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Hashtable _Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ParameterSetterList maintains a collection of IParameterSetter objects and applies them in order to each
|
||||||
|
/// parameter of the method. Each time a match occurs the next parameter is tried starting with the first
|
||||||
|
/// setter object until it is matched.
|
||||||
|
/// </summary>
|
||||||
|
public class ParameterSetterList
|
||||||
|
{
|
||||||
|
public void Add(IParameterSetter setter)
|
||||||
|
{
|
||||||
|
_List.Add(setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IParameterSetter[] ToArray()
|
||||||
|
{
|
||||||
|
return (IParameterSetter[])_List.ToArray(typeof(IParameterSetter));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
foreach(IParameterSetter Setter in _List)
|
||||||
|
Setter.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetParameters(MethodInfo Method)
|
||||||
|
{
|
||||||
|
ParameterInfo[] Params = Method.GetParameters();
|
||||||
|
object[] Values = new object[Params.Length];
|
||||||
|
//TODO: Update to iterate backwards
|
||||||
|
for(int i=0; i<Params.Length; ++i)
|
||||||
|
SetValue(Params[i], i, ref Values[i]);
|
||||||
|
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] GetParameters(MethodInfo Method, IParameterSetter LastSetter)
|
||||||
|
{
|
||||||
|
ParameterInfo[] Params = Method.GetParameters();
|
||||||
|
object[] Values = new object[Params.Length];
|
||||||
|
//TODO: Update to iterate backwards
|
||||||
|
for(int i=0; i<Params.Length; ++i)
|
||||||
|
{
|
||||||
|
if (!SetValue(Params[i], i, ref Values[i]))
|
||||||
|
LastSetter.GetParameterValue(Params[i], i, ref Values[i]);
|
||||||
|
}
|
||||||
|
return Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetValue(ParameterInfo Info, int i, ref object Value)
|
||||||
|
{
|
||||||
|
foreach(IParameterSetter Setter in _List)
|
||||||
|
{
|
||||||
|
if (Setter.GetParameterValue(Info, i, ref Value))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList _List = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IMethodCall represents a partially specified parameter data list and a method. This allows methods to be
|
||||||
|
/// dynamically late invoked for things like timers and other event driven frameworks.
|
||||||
|
/// </summary>
|
||||||
|
public interface IMethodCall
|
||||||
|
{
|
||||||
|
ParameterSetterList ParamList { get; }
|
||||||
|
object Execute();
|
||||||
|
object Execute(IParameterSetter Params);
|
||||||
|
void EventHandler(object obj, EventArgs e);
|
||||||
|
IAsyncResult BeginExecute(AsyncCallback callback, object obj);
|
||||||
|
IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate object Exec();
|
||||||
|
delegate object Exec2(IParameterSetter Params);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method call captures the data required to do a defered method call.
|
||||||
|
/// </summary>
|
||||||
|
public class DelegateMethodCall : MethodCallBase, IMethodCall
|
||||||
|
{
|
||||||
|
public DelegateMethodCall(Delegate f)
|
||||||
|
{
|
||||||
|
_f = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateMethodCall(Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
if (f.Method.GetParameters().Length < Params.Length)
|
||||||
|
throw new ArgumentException("Too many parameters specified for delegate", "f");
|
||||||
|
|
||||||
|
_f = f;
|
||||||
|
ParamList.Add(new OrderParameterSetter(Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public DelegateMethodCall(Delegate f, IParameterSetter Params)
|
||||||
|
{
|
||||||
|
_f = f;
|
||||||
|
ParamList.Add(Params);
|
||||||
|
}
|
||||||
|
|
||||||
|
Delegate _f;
|
||||||
|
|
||||||
|
public Delegate f
|
||||||
|
{
|
||||||
|
get { return _f; }
|
||||||
|
set { _f = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public MethodInfo Method
|
||||||
|
{
|
||||||
|
get { return _f.Method; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute()
|
||||||
|
{
|
||||||
|
return f.DynamicInvoke(GetParameterList(Method));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute(IParameterSetter Params)
|
||||||
|
{
|
||||||
|
return f.DynamicInvoke(GetParameterList(Method, Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EventHandler(object obj, EventArgs e)
|
||||||
|
{
|
||||||
|
Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Exec _exec;
|
||||||
|
public IAsyncResult BeginExecute(AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
_exec = new Exec(Execute);
|
||||||
|
return _exec.BeginInvoke(callback, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
Exec2 exec = new Exec2(Execute);
|
||||||
|
return exec.BeginInvoke(Params, callback, obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DynamicMethodCall : MethodCallBase, IMethodCall
|
||||||
|
{
|
||||||
|
public DynamicMethodCall(MethodInfo method)
|
||||||
|
{
|
||||||
|
_obj = null;
|
||||||
|
_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicMethodCall(object obj, MethodInfo method)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
_method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicMethodCall(object obj, MethodInfo method, IParameterSetter setter)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
_method = method;
|
||||||
|
ParamList.Add(setter);
|
||||||
|
}
|
||||||
|
|
||||||
|
object _obj;
|
||||||
|
MethodInfo _method;
|
||||||
|
|
||||||
|
public MethodInfo Method
|
||||||
|
{
|
||||||
|
get { return _method; }
|
||||||
|
set { _method = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute()
|
||||||
|
{
|
||||||
|
return _method.Invoke(_obj, GetParameterList(Method));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object Execute(IParameterSetter Params)
|
||||||
|
{
|
||||||
|
return _method.Invoke(_obj, GetParameterList(Method, Params));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EventHandler(object obj, EventArgs e)
|
||||||
|
{
|
||||||
|
Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
Exec _exec;
|
||||||
|
public IAsyncResult BeginExecute(AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
_exec = new Exec(Execute);
|
||||||
|
return _exec.BeginInvoke(callback, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncResult BeginExecute(IParameterSetter Params, AsyncCallback callback, object obj)
|
||||||
|
{
|
||||||
|
Exec2 exec = new Exec2(Execute);
|
||||||
|
return exec.BeginInvoke(Params, callback, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is a base class that handles the Parameter list management for the 2 dynamic method call methods.
|
||||||
|
/// </summary>
|
||||||
|
public class MethodCallBase
|
||||||
|
{
|
||||||
|
ParameterSetterList _ParamList = new ParameterSetterList();
|
||||||
|
|
||||||
|
public ParameterSetterList ParamList
|
||||||
|
{
|
||||||
|
get { return _ParamList; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected object[] GetParameterList(MethodInfo Method)
|
||||||
|
{
|
||||||
|
ParamList.reset();
|
||||||
|
object[] Params = ParamList.GetParameters(Method);
|
||||||
|
return Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected object[] GetParameterList(MethodInfo Method, IParameterSetter Params)
|
||||||
|
{
|
||||||
|
ParamList.reset();
|
||||||
|
object[] objParams = ParamList.GetParameters(Method, Params);
|
||||||
|
return objParams;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
35
UtilidadesTSL4net.c/Properties/AssemblyInfo.cs
Normal file
35
UtilidadesTSL4net.c/Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// La información general sobre un ensamblado se controla mediante el siguiente
|
||||||
|
// conjunto de atributos. Cambie estos atributos para modificar la información
|
||||||
|
// asociada con un ensamblado.
|
||||||
|
[assembly: AssemblyTitle("UtilidadesTSL4net.c")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany(".")]
|
||||||
|
[assembly: AssemblyProduct("UtilidadesTSL4net.c")]
|
||||||
|
[assembly: AssemblyCopyright("© . 2008")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Si establece ComVisible como false hace que los tipos de este ensamblado no sean visibles
|
||||||
|
// a los componentes COM. Si necesita obtener acceso a un tipo en este ensamblado desde
|
||||||
|
// COM, establezca el atributo ComVisible como true en este tipo.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// El siguiente GUID sirve como identificador de la biblioteca de tipos si este proyecto se expone a COM
|
||||||
|
[assembly: Guid("51c70542-3016-463d-8d03-d306aae697f8")]
|
||||||
|
|
||||||
|
// La información de versión de un ensamblado consta de los cuatro valores siguientes:
|
||||||
|
//
|
||||||
|
// Versión principal
|
||||||
|
// Versión secundaria
|
||||||
|
// Número de versión de compilación
|
||||||
|
// Revisión
|
||||||
|
//
|
||||||
|
// Puede especificar todos los valores o puede establecer como valores predeterminados los números de revisión y generación
|
||||||
|
// mediante el asterisco ('*'), como se muestra a continuación:
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
26
UtilidadesTSL4net.c/Properties/Settings.Designer.cs
generated
Normal file
26
UtilidadesTSL4net.c/Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// Este código fue generado por una herramienta.
|
||||||
|
// Versión de runtime:4.0.30319.1
|
||||||
|
//
|
||||||
|
// Los cambios en este archivo podrían causar un comportamiento incorrecto y se perderán si
|
||||||
|
// se vuelve a generar el código.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace Utilidadescsharp.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
6
UtilidadesTSL4net.c/Properties/Settings.settings
Normal file
6
UtilidadesTSL4net.c/Properties/Settings.settings
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
</SettingsFile>
|
||||||
63
UtilidadesTSL4net.c/ReportTimer.cs
Normal file
63
UtilidadesTSL4net.c/ReportTimer.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
public class ReportEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ReportEventArgs(DateTime Time, int reportNo) { EventTime = Time; ReportNo = reportNo; }
|
||||||
|
public int ReportNo;
|
||||||
|
public DateTime EventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void ReportEventHandler(object sender, ReportEventArgs e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for ReportTimer.
|
||||||
|
/// </summary>
|
||||||
|
public class ReportTimer : ScheduleTimerBase
|
||||||
|
{
|
||||||
|
public void AddReportEvent(IScheduledItem Schedule, int reportNo)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new Exception("You must set elapsed before adding Events");
|
||||||
|
AddJob(new TimerJob(Schedule, new DelegateMethodCall(Handler, Elapsed, reportNo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddAsyncReportEvent(IScheduledItem Schedule, int reportNo)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new Exception("You must set elapsed before adding Events");
|
||||||
|
TimerJob Event = new TimerJob(Schedule, new DelegateMethodCall(Handler, Elapsed, reportNo));
|
||||||
|
Event.SyncronizedEvent = false;
|
||||||
|
AddJob(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event ReportEventHandler Elapsed;
|
||||||
|
|
||||||
|
delegate void ConvertHandler(ReportEventHandler Handler, int ReportNo, object sender, DateTime time);
|
||||||
|
static ConvertHandler Handler = new ConvertHandler(Converter);
|
||||||
|
static void Converter(ReportEventHandler Handler, int ReportNo, object sender, DateTime time)
|
||||||
|
{
|
||||||
|
if (Handler == null)
|
||||||
|
throw new ArgumentNullException("Handler");
|
||||||
|
if (sender == null)
|
||||||
|
throw new ArgumentNullException("sender");
|
||||||
|
Handler(sender, new ReportEventArgs(time, ReportNo));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
75
UtilidadesTSL4net.c/ScheduleFilter.cs
Normal file
75
UtilidadesTSL4net.c/ScheduleFilter.cs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is an empty filter that does not filter any of the events.
|
||||||
|
/// </summary>
|
||||||
|
public class Filter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Empty = new Filter();
|
||||||
|
private Filter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This causes only the first event of the interval to be counted.
|
||||||
|
/// </summary>
|
||||||
|
public class FirstEventFilter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Filter = new FirstEventFilter();
|
||||||
|
private FirstEventFilter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
if (List.Count < 2)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
List.RemoveRange(1, List.Count-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This causes only the last event of the interval to be counted.
|
||||||
|
/// </summary>
|
||||||
|
public class LastEventFilter : IResultFilter
|
||||||
|
{
|
||||||
|
public static IResultFilter Filter = new LastEventFilter();
|
||||||
|
private LastEventFilter() {}
|
||||||
|
|
||||||
|
public void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (List == null)
|
||||||
|
return;
|
||||||
|
if (List.Count < 2)
|
||||||
|
return;
|
||||||
|
List.Sort();
|
||||||
|
List.RemoveRange(0, List.Count-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
254
UtilidadesTSL4net.c/ScheduleTimer.cs
Normal file
254
UtilidadesTSL4net.c/ScheduleTimer.cs
Normal file
@@ -0,0 +1,254 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Timers;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ScheduleTimer represents a timer that fires on a more human friendly schedule. For example it is easy to
|
||||||
|
/// set it to fire every day at 6:00PM. It is useful for batch jobs or alarms that might be difficult to
|
||||||
|
/// schedule with the native .net timers.
|
||||||
|
/// It is similar to the .net timer that it is based on with the start and stop methods functioning similarly.
|
||||||
|
/// The main difference is the event uses a different delegate and arguement since the .net timer argument
|
||||||
|
/// class is not creatable.
|
||||||
|
/// </summary>
|
||||||
|
public class ScheduleTimerBase : IDisposable
|
||||||
|
{
|
||||||
|
public ScheduleTimerBase()
|
||||||
|
{
|
||||||
|
_Timer = new Timer();
|
||||||
|
_Timer.AutoReset = false;
|
||||||
|
_Timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
|
||||||
|
_Jobs = new TimerJobList();
|
||||||
|
_LastTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer. This method passes in a delegate and the parameters similar to the Invoke method of windows forms.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule that this delegate is to be run on.</param>
|
||||||
|
/// <param name="f">The delegate to run</param>
|
||||||
|
/// <param name="Params">The method parameters to pass if you leave any DateTime parameters unbound, then they will be set with the scheduled run time of the
|
||||||
|
/// method. Any unbound object parameters will get this Job object passed in.</param>
|
||||||
|
public void AddJob(IScheduledItem Schedule, Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
_Jobs.Add(new TimerJob(Schedule, new DelegateMethodCall(f, Params)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer to operate asyncronously.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule that this delegate is to be run on.</param>
|
||||||
|
/// <param name="f">The delegate to run</param>
|
||||||
|
/// <param name="Params">The method parameters to pass if you leave any DateTime parameters unbound, then they will be set with the scheduled run time of the
|
||||||
|
/// method. Any unbound object parameters will get this Job object passed in.</param>
|
||||||
|
public void AddAsyncJob(IScheduledItem Schedule, Delegate f, params object[] Params)
|
||||||
|
{
|
||||||
|
TimerJob Event = new TimerJob(Schedule, new DelegateMethodCall(f, Params));
|
||||||
|
Event.SyncronizedEvent = false;
|
||||||
|
_Jobs.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a job to the timer.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Event"></param>
|
||||||
|
public void AddJob(TimerJob Event)
|
||||||
|
{
|
||||||
|
_Jobs.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears out all scheduled jobs.
|
||||||
|
/// </summary>
|
||||||
|
public void ClearJobs()
|
||||||
|
{
|
||||||
|
_Jobs.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Begins executing all assigned jobs at the scheduled times
|
||||||
|
/// </summary>
|
||||||
|
public void Start()
|
||||||
|
{
|
||||||
|
_StopFlag = false;
|
||||||
|
QueueNextTime(EventStorage.ReadLastTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Halts executing all jobs. When the timer is restarted all jobs that would have run while the timer was stopped are re-tried.
|
||||||
|
/// </summary>
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
_StopFlag = true;
|
||||||
|
_Timer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// EventStorage determines the method used to store the last event fire time. It defaults to keeping it in memory.
|
||||||
|
/// </summary>
|
||||||
|
public IEventStorage EventStorage = new LocalEventStorage();
|
||||||
|
public event ExceptionEventHandler Error;
|
||||||
|
|
||||||
|
#region Private Methods and Fields
|
||||||
|
/// <summary>
|
||||||
|
/// This is here to enhance accuracy. Even if nothing is scheduled the timer sleeps for a maximum of 1 minute.
|
||||||
|
/// </summary>
|
||||||
|
private static TimeSpan MAX_INTERVAL = new TimeSpan(0, 1, 0);
|
||||||
|
|
||||||
|
private DateTime _LastTime;
|
||||||
|
private Timer _Timer;
|
||||||
|
private TimerJobList _Jobs;
|
||||||
|
private volatile bool _StopFlag;
|
||||||
|
|
||||||
|
private double NextInterval(DateTime thisTime)
|
||||||
|
{
|
||||||
|
TimeSpan interval = _Jobs.NextRunTime(thisTime)-thisTime;
|
||||||
|
if (interval > MAX_INTERVAL)
|
||||||
|
interval = MAX_INTERVAL;
|
||||||
|
//Handles the case of 0 wait time, the interval property requires a duration > 0.
|
||||||
|
return (interval.TotalMilliseconds == 0) ? 1 : interval.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void QueueNextTime(DateTime thisTime)
|
||||||
|
{
|
||||||
|
_Timer.Interval = NextInterval(thisTime);
|
||||||
|
System.Diagnostics.Debug.WriteLine(_Timer.Interval);
|
||||||
|
_LastTime = thisTime;
|
||||||
|
EventStorage.RecordLastTime(thisTime);
|
||||||
|
_Timer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_Jobs == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_Timer.Stop();
|
||||||
|
|
||||||
|
foreach(TimerJob Event in _Jobs.Jobs)
|
||||||
|
{
|
||||||
|
try { Event.Execute(this, _LastTime, e.SignalTime, Error); }
|
||||||
|
catch (Exception ex) { OnError(DateTime.Now, Event, ex); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
OnError(DateTime.Now, null, ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (_StopFlag == false)
|
||||||
|
QueueNextTime(e.SignalTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnError(DateTime eventTime, TimerJob job, Exception e)
|
||||||
|
{
|
||||||
|
if (Error == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try { Error(this, new ExceptionEventArgs(eventTime, e)); }
|
||||||
|
catch (Exception) {}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_Timer != null)
|
||||||
|
_Timer.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ScheduleTimer : ScheduleTimerBase
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Add event is used in conjunction with the Elaspsed event handler. Set the Elapsed handler, add your schedule and call start.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Schedule">The schedule to fire the event at. Adding additional schedules will cause the event to fire whenever either schedule calls for it.</param>
|
||||||
|
public void AddEvent(IScheduledItem Schedule)
|
||||||
|
{
|
||||||
|
if (Elapsed == null)
|
||||||
|
throw new ArgumentNullException("Elapsed", "member variable is null.");
|
||||||
|
|
||||||
|
AddJob(new TimerJob(Schedule, new DelegateMethodCall(Elapsed)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The event to fire when you only need to fire one event.
|
||||||
|
/// </summary>
|
||||||
|
public event ScheduledEventHandler Elapsed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ExceptionEventArgs allows exceptions to be captured and sent to the OnError event of the timer.
|
||||||
|
/// </summary>
|
||||||
|
public class ExceptionEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ExceptionEventArgs(DateTime eventTime, Exception e)
|
||||||
|
{
|
||||||
|
EventTime = eventTime;
|
||||||
|
Error = e;
|
||||||
|
}
|
||||||
|
public DateTime EventTime;
|
||||||
|
public Exception Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ExceptionEventHandler is the method type used by the OnError event for the timer.
|
||||||
|
/// </summary>
|
||||||
|
public delegate void ExceptionEventHandler(object sender, ExceptionEventArgs Args);
|
||||||
|
|
||||||
|
public class ScheduledEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public ScheduledEventArgs(DateTime eventTime)
|
||||||
|
{
|
||||||
|
EventTime = eventTime;
|
||||||
|
}
|
||||||
|
public DateTime EventTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void ScheduledEventHandler(object sender, ScheduledEventArgs e);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The IResultFilter interface represents filters that either sort the events for an interval or
|
||||||
|
/// remove duplicate events either selecting the first or the last event.
|
||||||
|
/// </summary>
|
||||||
|
public interface IResultFilter
|
||||||
|
{
|
||||||
|
void FilterResultsInInterval(DateTime Start, DateTime End, ArrayList List);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// IEventStorage is used to provide persistance of schedule during service shutdowns.
|
||||||
|
/// </summary>
|
||||||
|
public interface IEventStorage
|
||||||
|
{
|
||||||
|
void RecordLastTime(DateTime Time);
|
||||||
|
DateTime ReadLastTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
80
UtilidadesTSL4net.c/ScheduledItems/BlockWrapper.cs
Normal file
80
UtilidadesTSL4net.c/ScheduledItems/BlockWrapper.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class will be used to implement a filter that enables a window of activity. For cases where you want to
|
||||||
|
/// run every 15 minutes between 6:00 AM and 5:00 PM. Or just on weekdays or weekends.
|
||||||
|
/// </summary>
|
||||||
|
public class BlockWrapper : IScheduledItem
|
||||||
|
{
|
||||||
|
public BlockWrapper(IScheduledItem item, string StrBase, string BeginOffset, string EndOffset)
|
||||||
|
{
|
||||||
|
_Item = item;
|
||||||
|
_Begin = new ScheduledTime(StrBase, BeginOffset);
|
||||||
|
_End = new ScheduledTime(StrBase, EndOffset);
|
||||||
|
}
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = NextRunTime(Next, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
return NextRunTime(time, 100, AllowExact);
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime NextRunTime(DateTime time, int count, bool AllowExact)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
throw new Exception("Invalid block wrapper combination.");
|
||||||
|
|
||||||
|
DateTime
|
||||||
|
temp = _Item.NextRunTime(time, AllowExact),
|
||||||
|
begin = _Begin.NextRunTime(time, true),
|
||||||
|
end = _End.NextRunTime(time, true);
|
||||||
|
System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2} {3}", time, begin, end, temp));
|
||||||
|
bool A = temp > end, B = temp < begin, C = end < begin;
|
||||||
|
System.Diagnostics.Debug.WriteLine(string.Format("{0} {1} {2}", A, B, C));
|
||||||
|
if (C)
|
||||||
|
{
|
||||||
|
if (A && B)
|
||||||
|
return NextRunTime(begin, --count, false);
|
||||||
|
else
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!A && !B)
|
||||||
|
return temp;
|
||||||
|
if (!A)
|
||||||
|
return NextRunTime(begin, --count, false);
|
||||||
|
else
|
||||||
|
return NextRunTime(end, --count, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private IScheduledItem _Item;
|
||||||
|
private ScheduledTime _Begin, _End;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
UtilidadesTSL4net.c/ScheduledItems/EventInstance.cs
Normal file
52
UtilidadesTSL4net.c/ScheduledItems/EventInstance.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// There have been quite a few requests to allow scheduling of multiple delegates and method parameter data
|
||||||
|
/// from the same timer. This class allows you to match the event with the time that it fired. I want to keep
|
||||||
|
/// the same simple implementation of the EventQueue and interval classes since they can be reused elsewhere.
|
||||||
|
/// The timer should be responsible for matching this data up.
|
||||||
|
/// </summary>
|
||||||
|
public class EventInstance : IComparable
|
||||||
|
{
|
||||||
|
public EventInstance(DateTime time, IScheduledItem scheduleItem, object data)
|
||||||
|
{
|
||||||
|
Time = time;
|
||||||
|
ScheduleItem = scheduleItem;
|
||||||
|
Data = data;
|
||||||
|
}
|
||||||
|
public DateTime Time;
|
||||||
|
public IScheduledItem ScheduleItem;
|
||||||
|
public object Data;
|
||||||
|
|
||||||
|
public int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (obj is EventInstance)
|
||||||
|
return Time.CompareTo(((EventInstance)obj).Time);
|
||||||
|
if (obj is DateTime)
|
||||||
|
return Time.CompareTo((DateTime)obj);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
81
UtilidadesTSL4net.c/ScheduledItems/EventQueue.cs
Normal file
81
UtilidadesTSL4net.c/ScheduledItems/EventQueue.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The event queue is a collection of scheduled items that represents the union of all child scheduled items.
|
||||||
|
/// This is useful for events that occur every 10 minutes or at multiple intervals not covered by the simple
|
||||||
|
/// scheduled items.
|
||||||
|
/// </summary>
|
||||||
|
public class EventQueue : IScheduledItem
|
||||||
|
{
|
||||||
|
public EventQueue()
|
||||||
|
{
|
||||||
|
_List = new ArrayList();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a ScheduledTime to the queue.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The scheduled time to add</param>
|
||||||
|
public void Add(IScheduledItem time)
|
||||||
|
{
|
||||||
|
_List.Add(time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the list of scheduled times.
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_List.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the running time for all events in the list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Begin">The beginning time of the interval</param>
|
||||||
|
/// <param name="End">The end time of the interval</param>
|
||||||
|
/// <param name="List">The list to add times to.</param>
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
foreach(IScheduledItem st in _List)
|
||||||
|
st.AddEventsInInterval(Begin, End, List);
|
||||||
|
List.Sort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the first time after the starting time for all events in the list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time.</param>
|
||||||
|
/// <param name="AllowExact">If this is true then it allows the return time to match the time parameter, false forces the return time to be greater then the time parameter</param>
|
||||||
|
/// <returns>Either the next event after the input time or greater or equal to depending on the AllowExact parameter.</returns>
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime next = DateTime.MaxValue;
|
||||||
|
//Get minimum datetime from the list.
|
||||||
|
foreach(IScheduledItem st in _List)
|
||||||
|
{
|
||||||
|
DateTime Proposed = st.NextRunTime(time, AllowExact);
|
||||||
|
next = (Proposed < next) ? Proposed : next;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
private ArrayList _List;
|
||||||
|
}
|
||||||
|
}
|
||||||
177
UtilidadesTSL4net.c/ScheduledItems/ScheduledTime.cs
Normal file
177
UtilidadesTSL4net.c/ScheduledItems/ScheduledTime.cs
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
public enum EventTimeBase
|
||||||
|
{
|
||||||
|
BySecond = 1,
|
||||||
|
ByMinute = 2,
|
||||||
|
Hourly = 3,
|
||||||
|
Daily = 4,
|
||||||
|
Weekly = 5,
|
||||||
|
Monthly = 6,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a simple schedule. It can represent a repeating event that occurs anywhere from every
|
||||||
|
/// second to once a month. It consists of an enumeration to mark the interval and an offset from that interval.
|
||||||
|
/// For example new ScheduledTime(Hourly, new TimeSpan(0, 15, 0)) would represent an event that fired 15 minutes
|
||||||
|
/// after the hour every hour.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class ScheduledTime : IScheduledItem
|
||||||
|
{
|
||||||
|
public ScheduledTime(EventTimeBase Base, TimeSpan Offset)
|
||||||
|
{
|
||||||
|
_Base = Base;
|
||||||
|
_Offset = Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// intializes a simple scheduled time element from a pair of strings.
|
||||||
|
/// Here are the supported formats
|
||||||
|
///
|
||||||
|
/// BySecond - single integer representing the offset in ms
|
||||||
|
/// ByMinute - A comma seperate list of integers representing the number of seconds and ms
|
||||||
|
/// Hourly - A comma seperated list of integers representing the number of minutes, seconds and ms
|
||||||
|
/// Daily - A time in hh:mm:ss AM/PM format
|
||||||
|
/// Weekly - n, time where n represents an integer and time is a time in the Daily format
|
||||||
|
/// Monthly - the same format as weekly.
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="StrBase">A string representing the base enumeration for the scheduled time</param>
|
||||||
|
/// <param name="StrOffset">A string representing the offset for the time.</param>
|
||||||
|
public ScheduledTime(string StrBase, string StrOffset)
|
||||||
|
{
|
||||||
|
//TODO:Create an IScheduled time factory method.
|
||||||
|
_Base = (EventTimeBase)Enum.Parse(typeof(EventTimeBase), StrBase, true);
|
||||||
|
Init(StrOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ArrayAccess(string[] Arr, int i)
|
||||||
|
{
|
||||||
|
if (i >= Arr.Length)
|
||||||
|
return 0;
|
||||||
|
return int.Parse(Arr[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = IncInterval(Next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime NextRun = LastSyncForTime(time) + _Offset;
|
||||||
|
if (NextRun == time && AllowExact)
|
||||||
|
return time;
|
||||||
|
if (NextRun > time)
|
||||||
|
return NextRun;
|
||||||
|
return IncInterval(NextRun);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DateTime LastSyncForTime(DateTime time)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second);
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, 0);
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day, time.Hour, 0, 0);
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
return new DateTime(time.Year, time.Month, time.Day);
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
return (new DateTime(time.Year, time.Month, time.Day)).AddDays(-(int)time.DayOfWeek);
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
return new DateTime(time.Year, time.Month, 1);
|
||||||
|
}
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime IncInterval(DateTime Last)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
return Last.AddSeconds(1);
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
return Last.AddMinutes(1);
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
return Last.AddHours(1);
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
return Last.AddDays(1);
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
return Last.AddDays(7);
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
return Last.AddMonths(1);
|
||||||
|
}
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init(string StrOffset)
|
||||||
|
{
|
||||||
|
switch (_Base)
|
||||||
|
{
|
||||||
|
case EventTimeBase.BySecond:
|
||||||
|
_Offset = new TimeSpan(0, 0, 0, 0, int.Parse(StrOffset));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.ByMinute:
|
||||||
|
string[] ArrMinute = StrOffset.Split(',');
|
||||||
|
_Offset = new TimeSpan(0, 0, 0, ArrayAccess(ArrMinute, 0), ArrayAccess(ArrMinute, 1));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Hourly:
|
||||||
|
string[] ArrHour = StrOffset.Split(',');
|
||||||
|
_Offset = new TimeSpan(0, 0, ArrayAccess(ArrHour, 0), ArrayAccess(ArrHour, 1), ArrayAccess(ArrHour, 2));
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Daily:
|
||||||
|
DateTime Daytime = DateTime.Parse(StrOffset);
|
||||||
|
_Offset = new TimeSpan(0, Daytime.Hour, Daytime.Minute, Daytime.Second, Daytime.Millisecond);
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Weekly:
|
||||||
|
string[] ArrWeek = StrOffset.Split(',');
|
||||||
|
if (ArrWeek.Length != 2)
|
||||||
|
throw new Exception("Weekly offset must be in the format n, time where n is the day of the week starting with 0 for sunday");
|
||||||
|
DateTime WeekTime = DateTime.Parse(ArrWeek[1]);
|
||||||
|
_Offset = new TimeSpan(int.Parse(ArrWeek[0]), WeekTime.Hour, WeekTime.Minute, WeekTime.Second, WeekTime.Millisecond);
|
||||||
|
break;
|
||||||
|
case EventTimeBase.Monthly:
|
||||||
|
string[] ArrMonth = StrOffset.Split(',');
|
||||||
|
if (ArrMonth.Length != 2)
|
||||||
|
throw new Exception("Monthly offset must be in the format n, time where n is the day of the month starting with 1 for the first day of the month.");
|
||||||
|
DateTime MonthTime = DateTime.Parse(ArrMonth[1]);
|
||||||
|
_Offset = new TimeSpan(int.Parse(ArrMonth[0])-1, MonthTime.Hour, MonthTime.Minute, MonthTime.Second, MonthTime.Millisecond);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Exception("Invalid base specified for timer.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventTimeBase _Base;
|
||||||
|
private TimeSpan _Offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
90
UtilidadesTSL4net.c/ScheduledItems/SimpleInterval.cs
Normal file
90
UtilidadesTSL4net.c/ScheduledItems/SimpleInterval.cs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The simple interval represents the simple scheduling that .net supports natively. It consists of a start
|
||||||
|
/// absolute time and an interval that is counted off from the start time.
|
||||||
|
/// </summary>
|
||||||
|
[Serializable]
|
||||||
|
public class SimpleInterval : IScheduledItem
|
||||||
|
{
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval, int count)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = StartTime + TimeSpan.FromTicks(Interval.Ticks*count);
|
||||||
|
}
|
||||||
|
public SimpleInterval(DateTime StartTime, TimeSpan Interval, DateTime EndTime)
|
||||||
|
{
|
||||||
|
_Interval = Interval;
|
||||||
|
_StartTime = StartTime;
|
||||||
|
_EndTime = EndTime;
|
||||||
|
}
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, ArrayList List)
|
||||||
|
{
|
||||||
|
if (End <= _StartTime)
|
||||||
|
return;
|
||||||
|
DateTime Next = NextRunTime(Begin, true);
|
||||||
|
while (Next < End)
|
||||||
|
{
|
||||||
|
List.Add(Next);
|
||||||
|
Next = NextRunTime(Next, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
DateTime returnTime = NextRunTimeInt(time, AllowExact);
|
||||||
|
Debug.WriteLine(time);
|
||||||
|
Debug.WriteLine(returnTime);
|
||||||
|
Debug.WriteLine(_EndTime);
|
||||||
|
return (returnTime >= _EndTime) ? DateTime.MaxValue : returnTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DateTime NextRunTimeInt(DateTime time, bool AllowExact)
|
||||||
|
{
|
||||||
|
TimeSpan Span = time-_StartTime;
|
||||||
|
if (Span < TimeSpan.Zero)
|
||||||
|
return _StartTime;
|
||||||
|
if (ExactMatch(time))
|
||||||
|
return AllowExact ? time : time + _Interval;
|
||||||
|
uint msRemaining = (uint)(_Interval.TotalMilliseconds - ((uint)Span.TotalMilliseconds % (uint)_Interval.TotalMilliseconds));
|
||||||
|
return time.AddMilliseconds(msRemaining);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ExactMatch(DateTime time)
|
||||||
|
{
|
||||||
|
TimeSpan Span = time-_StartTime;
|
||||||
|
if (Span < TimeSpan.Zero)
|
||||||
|
return false;
|
||||||
|
return (Span.TotalMilliseconds % _Interval.TotalMilliseconds) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TimeSpan _Interval;
|
||||||
|
private DateTime _StartTime;
|
||||||
|
private DateTime _EndTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
UtilidadesTSL4net.c/ScheduledItems/SingleEvent.cs
Normal file
45
UtilidadesTSL4net.c/ScheduledItems/SingleEvent.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>Single event represents an event which only fires once.</summary>
|
||||||
|
public class SingleEvent : IScheduledItem
|
||||||
|
{
|
||||||
|
public SingleEvent(DateTime eventTime)
|
||||||
|
{
|
||||||
|
_EventTime = eventTime;
|
||||||
|
}
|
||||||
|
#region IScheduledItem Members
|
||||||
|
|
||||||
|
public void AddEventsInInterval(DateTime Begin, DateTime End, System.Collections.ArrayList List)
|
||||||
|
{
|
||||||
|
if (Begin <= _EventTime && End > _EventTime)
|
||||||
|
List.Add(_EventTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool IncludeStartTime)
|
||||||
|
{
|
||||||
|
if (IncludeStartTime)
|
||||||
|
return (_EventTime >= time) ? _EventTime : DateTime.MaxValue;
|
||||||
|
else
|
||||||
|
return (_EventTime > time) ? _EventTime : DateTime.MaxValue;
|
||||||
|
}
|
||||||
|
private DateTime _EventTime;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
181
UtilidadesTSL4net.c/TimerJob.cs
Normal file
181
UtilidadesTSL4net.c/TimerJob.cs
Normal file
@@ -0,0 +1,181 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
* Copyright Andy Brummer 2004-2005
|
||||||
|
*
|
||||||
|
* This code is provided "as is", with absolutely no warranty expressed
|
||||||
|
* or implied. Any use is at your own risk.
|
||||||
|
*
|
||||||
|
* This code may be used in compiled form in any way you desire. This
|
||||||
|
* file may be redistributed unmodified by any means provided it is
|
||||||
|
* not sold for profit without the authors written consent, and
|
||||||
|
* providing that this notice and the authors name is included. If
|
||||||
|
* the source code in this file is used in any commercial application
|
||||||
|
* then a simple email would be nice.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Timers;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Schedule
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Timer job groups a schedule, syncronization data, a result filter, method information and an enabled state so that multiple jobs
|
||||||
|
/// can be managed by the same timer. Each one operating independently of the others with different syncronization and recovery settings.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerJob
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public TimerJob(IScheduledItem schedule, IMethodCall method)
|
||||||
|
{
|
||||||
|
Schedule = schedule;
|
||||||
|
Method = method;
|
||||||
|
_ExecuteHandler = new ExecuteHandler(ExecuteInternal);
|
||||||
|
}
|
||||||
|
public IScheduledItem Schedule;
|
||||||
|
public bool SyncronizedEvent = true;
|
||||||
|
public IResultFilter Filter;
|
||||||
|
public IMethodCall Method;
|
||||||
|
// public IJobLog Log;
|
||||||
|
public bool Enabled = true;
|
||||||
|
|
||||||
|
public DateTime NextRunTime(DateTime time, bool IncludeStartTime)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return DateTime.MaxValue;
|
||||||
|
return Schedule.NextRunTime(time, IncludeStartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute(object sender, DateTime Begin, DateTime End, ExceptionEventHandler Error)
|
||||||
|
{
|
||||||
|
if (!Enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ArrayList EventList = new ArrayList();
|
||||||
|
Schedule.AddEventsInInterval(Begin, End, EventList);
|
||||||
|
|
||||||
|
if (Filter != null)
|
||||||
|
Filter.FilterResultsInInterval(Begin, End, EventList);
|
||||||
|
|
||||||
|
foreach(DateTime EventTime in EventList)
|
||||||
|
{
|
||||||
|
if (SyncronizedEvent)
|
||||||
|
_ExecuteHandler(sender, EventTime, Error);
|
||||||
|
else
|
||||||
|
_ExecuteHandler.BeginInvoke(sender, EventTime, Error, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ExecuteInternal(object sender, DateTime EventTime, ExceptionEventHandler Error)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
TimerParameterSetter Setter = new TimerParameterSetter(EventTime, sender);
|
||||||
|
Method.Execute(Setter);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
if (Error != null)
|
||||||
|
try { Error(this, new ExceptionEventArgs(EventTime, ex)); } catch {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private delegate void ExecuteHandler(object sender, DateTime EventTime, ExceptionEventHandler Error);
|
||||||
|
|
||||||
|
private ExecuteHandler _ExecuteHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Timer job manages a group of timer jobs.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerJobList
|
||||||
|
{
|
||||||
|
public TimerJobList()
|
||||||
|
{
|
||||||
|
_List = new ArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Add(TimerJob Event)
|
||||||
|
{
|
||||||
|
_List.Add(Event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_List.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the next time any of the jobs in the list will run. Allows matching the exact start time. If no matches are found the return
|
||||||
|
/// is DateTime.MaxValue;
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The starting time for the interval being queried. This time is included in the interval</param>
|
||||||
|
/// <returns>The first absolute date one of the jobs will execute on. If none of the jobs needs to run DateTime.MaxValue is returned.</returns>
|
||||||
|
public DateTime NextRunTime(DateTime time)
|
||||||
|
{
|
||||||
|
DateTime next = DateTime.MaxValue;
|
||||||
|
//Get minimum datetime from the list.
|
||||||
|
foreach(TimerJob Job in _List)
|
||||||
|
{
|
||||||
|
DateTime Proposed = Job.NextRunTime(time, true);
|
||||||
|
next = (Proposed < next) ? Proposed : next;
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimerJob[] Jobs
|
||||||
|
{
|
||||||
|
get { return (TimerJob[])_List.ToArray(typeof(TimerJob)); }
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayList _List;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The timer job allows delegates to be specified with unbound parameters. This ParameterSetter assigns all unbound datetime parameters
|
||||||
|
/// with the specified time and all unbound object parameters with the calling object.
|
||||||
|
/// </summary>
|
||||||
|
public class TimerParameterSetter : IParameterSetter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initalize the ParameterSetter with the time to pass to unbound time parameters and object to pass to unbound object parameters.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="time">The time to pass to the unbound DateTime parameters</param>
|
||||||
|
/// <param name="sender">The object to pass to the unbound object parameters</param>
|
||||||
|
public TimerParameterSetter(DateTime time, object sender)
|
||||||
|
{
|
||||||
|
_time = time;
|
||||||
|
_sender = sender;
|
||||||
|
}
|
||||||
|
public void reset()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public bool GetParameterValue(ParameterInfo pi, int ParameterLoc, ref object parameter)
|
||||||
|
{
|
||||||
|
switch(pi.ParameterType.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "datetime":
|
||||||
|
parameter = _time;
|
||||||
|
return true;
|
||||||
|
case "object":
|
||||||
|
parameter = _sender;
|
||||||
|
return true;
|
||||||
|
case "scheduledeventargs":
|
||||||
|
parameter = new ScheduledEventArgs(_time);
|
||||||
|
return true;
|
||||||
|
case "eventargs":
|
||||||
|
parameter = new ScheduledEventArgs(_time);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
DateTime _time;
|
||||||
|
object _sender;
|
||||||
|
}
|
||||||
|
}
|
||||||
132
UtilidadesTSL4net.c/UtilidadesTSL4net.c.csproj
Normal file
132
UtilidadesTSL4net.c/UtilidadesTSL4net.c.csproj
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProductVersion>9.0.30729</ProductVersion>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<ProjectGuid>{BF2447F5-65A1-4A47-A16E-F2227634E050}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Utilidadescsharp</RootNamespace>
|
||||||
|
<AssemblyName>UtilidadesTSL4net.c</AssemblyName>
|
||||||
|
<FileUpgradeFlags>
|
||||||
|
</FileUpgradeFlags>
|
||||||
|
<OldToolsVersion>3.5</OldToolsVersion>
|
||||||
|
<UpgradeBackupLocation>
|
||||||
|
</UpgradeBackupLocation>
|
||||||
|
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||||
|
<PublishUrl>publish\</PublishUrl>
|
||||||
|
<Install>true</Install>
|
||||||
|
<InstallFrom>Disk</InstallFrom>
|
||||||
|
<UpdateEnabled>false</UpdateEnabled>
|
||||||
|
<UpdateMode>Foreground</UpdateMode>
|
||||||
|
<UpdateInterval>7</UpdateInterval>
|
||||||
|
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||||
|
<UpdatePeriodically>false</UpdatePeriodically>
|
||||||
|
<UpdateRequired>false</UpdateRequired>
|
||||||
|
<MapFileExtensions>true</MapFileExtensions>
|
||||||
|
<ApplicationRevision>0</ApplicationRevision>
|
||||||
|
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||||
|
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||||
|
<UseApplicationTrust>false</UseApplicationTrust>
|
||||||
|
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||||
|
<SccProjectName>SAK</SccProjectName>
|
||||||
|
<SccLocalPath>SAK</SccLocalPath>
|
||||||
|
<SccAuxPath>SAK</SccAuxPath>
|
||||||
|
<SccProvider>SAK</SccProvider>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||||
|
<DocumentationFile>
|
||||||
|
</DocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Windows.Forms" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="EventStorage.cs" />
|
||||||
|
<Compile Include="IScheduledItem.cs" />
|
||||||
|
<Compile Include="MethodCall.cs" />
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="ReportTimer.cs" />
|
||||||
|
<Compile Include="ScheduledItems\BlockWrapper.cs" />
|
||||||
|
<Compile Include="ScheduledItems\EventInstance.cs" />
|
||||||
|
<Compile Include="ScheduledItems\EventQueue.cs" />
|
||||||
|
<Compile Include="ScheduledItems\ScheduledTime.cs" />
|
||||||
|
<Compile Include="ScheduledItems\SimpleInterval.cs" />
|
||||||
|
<Compile Include="ScheduledItems\SingleEvent.cs" />
|
||||||
|
<Compile Include="ScheduleFilter.cs" />
|
||||||
|
<Compile Include="ScheduleTimer.cs" />
|
||||||
|
<Compile Include="TimerJob.cs" />
|
||||||
|
<Compile Include="ucImagen.cs">
|
||||||
|
<SubType>UserControl</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="ucImagen.resx">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<DependentUpon>ucImagen.cs</DependentUpon>
|
||||||
|
</EmbeddedResource>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||||
|
<Install>false</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Windows Installer 3.1</ProductName>
|
||||||
|
<Install>true</Install>
|
||||||
|
</BootstrapperPackage>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
Other similar extension points exist, see Microsoft.Common.targets.
|
||||||
|
<Target Name="BeforeBuild">
|
||||||
|
</Target>
|
||||||
|
<Target Name="AfterBuild">
|
||||||
|
</Target>
|
||||||
|
-->
|
||||||
|
</Project>
|
||||||
202
UtilidadesTSL4net.c/ucImagen.cs
Normal file
202
UtilidadesTSL4net.c/ucImagen.cs
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Imagen
|
||||||
|
{
|
||||||
|
public enum SizeMode
|
||||||
|
{
|
||||||
|
Scrollable,
|
||||||
|
RatioStretch
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for Viewer.
|
||||||
|
/// </summary>
|
||||||
|
public class Imagen : System.Windows.Forms.UserControl
|
||||||
|
{
|
||||||
|
private System.Windows.Forms.PictureBox pictureBox1;
|
||||||
|
private System.ComponentModel.IContainer components;
|
||||||
|
private SizeMode sizeMode;
|
||||||
|
|
||||||
|
public Imagen()
|
||||||
|
{
|
||||||
|
// This call is required by the Windows.Forms Form Designer.
|
||||||
|
InitializeComponent();
|
||||||
|
this.ImageSizeMode = SizeMode.RatioStretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (components != null)
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image Image
|
||||||
|
{
|
||||||
|
get { return this.pictureBox1.Image; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.pictureBox1.Image = value;
|
||||||
|
this.SetLayout();
|
||||||
|
//this.ChangeSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public SizeMode ImageSizeMode
|
||||||
|
{
|
||||||
|
get { return this.sizeMode; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.sizeMode = value;
|
||||||
|
this.AutoScroll = (this.sizeMode == SizeMode.Scrollable);
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RatioStretch()
|
||||||
|
{
|
||||||
|
float pRatio = (float)this.Width / this.Height;
|
||||||
|
float imRatio = (float)this.pictureBox1.Image.Width / this.pictureBox1.Image.Height;
|
||||||
|
|
||||||
|
if (this.Width >= this.pictureBox1.Image.Width && this.Height >= this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.pictureBox1.Image.Width;
|
||||||
|
this.pictureBox1.Height = this.pictureBox1.Image.Height;
|
||||||
|
}
|
||||||
|
else if (this.Width > this.pictureBox1.Image.Width && this.Height < this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
else if (this.Width < this.pictureBox1.Image.Width && this.Height > this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
else if (this.Width < this.pictureBox1.Image.Width && this.Height < this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
if (this.Width >= this.Height)
|
||||||
|
{
|
||||||
|
//width image
|
||||||
|
if (this.pictureBox1.Image.Width >= this.pictureBox1.Image.Height && imRatio >= pRatio)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//width image
|
||||||
|
if (this.pictureBox1.Image.Width < this.pictureBox1.Image.Height && imRatio < pRatio)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
else // height image
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.CenterImage();
|
||||||
|
}
|
||||||
|
private void Scrollable()
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.pictureBox1.Image.Width;
|
||||||
|
this.pictureBox1.Height = this.pictureBox1.Image.Height;
|
||||||
|
this.CenterImage();
|
||||||
|
}
|
||||||
|
private void SetLayout()
|
||||||
|
{
|
||||||
|
if (this.pictureBox1.Image == null)
|
||||||
|
return;
|
||||||
|
if (this.sizeMode == SizeMode.RatioStretch)
|
||||||
|
this.RatioStretch();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.AutoScroll = false;
|
||||||
|
this.Scrollable();
|
||||||
|
this.AutoScroll = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void CenterImage()
|
||||||
|
{
|
||||||
|
int top = (int)((this.Height - this.pictureBox1.Height) / 2.0);
|
||||||
|
int left = (int)((this.Width - this.pictureBox1.Width) / 2.0);
|
||||||
|
if (top < 0)
|
||||||
|
top = 0;
|
||||||
|
if (left < 0)
|
||||||
|
left = 0;
|
||||||
|
this.pictureBox1.Top = top;
|
||||||
|
this.pictureBox1.Left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBox1
|
||||||
|
//
|
||||||
|
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Default;
|
||||||
|
this.pictureBox1.Location = new System.Drawing.Point(24, 32);
|
||||||
|
this.pictureBox1.Name = "pictureBox1";
|
||||||
|
this.pictureBox1.Size = new System.Drawing.Size(296, 208);
|
||||||
|
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||||
|
this.pictureBox1.TabIndex = 0;
|
||||||
|
this.pictureBox1.TabStop = false;
|
||||||
|
//
|
||||||
|
// Imagen
|
||||||
|
//
|
||||||
|
this.AutoScroll = true;
|
||||||
|
this.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.Controls.Add(this.pictureBox1);
|
||||||
|
this.Name = "Imagen";
|
||||||
|
this.Size = new System.Drawing.Size(352, 272);
|
||||||
|
this.Load += new System.EventHandler(this.Viewer_Load);
|
||||||
|
this.Resize += new System.EventHandler(this.Viewer_Resize);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void Viewer_Load(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = 0;
|
||||||
|
this.pictureBox1.Height = 0;
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Viewer_Resize(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
120
UtilidadesTSL4net.c/ucImagen.resx
Normal file
120
UtilidadesTSL4net.c/ucImagen.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
202
ucImagen.cs
Normal file
202
ucImagen.cs
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Data;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
namespace UtilidadesCSharp.Imagen
|
||||||
|
{
|
||||||
|
public enum SizeMode
|
||||||
|
{
|
||||||
|
Scrollable,
|
||||||
|
RatioStretch
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for Viewer.
|
||||||
|
/// </summary>
|
||||||
|
public class Imagen : System.Windows.Forms.UserControl
|
||||||
|
{
|
||||||
|
private System.Windows.Forms.PictureBox pictureBox1;
|
||||||
|
private System.ComponentModel.IContainer components;
|
||||||
|
private SizeMode sizeMode;
|
||||||
|
|
||||||
|
public Imagen()
|
||||||
|
{
|
||||||
|
// This call is required by the Windows.Forms Form Designer.
|
||||||
|
InitializeComponent();
|
||||||
|
this.ImageSizeMode = SizeMode.RatioStretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clean up any resources being used.
|
||||||
|
/// </summary>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (components != null)
|
||||||
|
{
|
||||||
|
components.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Image Image
|
||||||
|
{
|
||||||
|
get { return this.pictureBox1.Image; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.pictureBox1.Image = value;
|
||||||
|
this.SetLayout();
|
||||||
|
//this.ChangeSize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public SizeMode ImageSizeMode
|
||||||
|
{
|
||||||
|
get { return this.sizeMode; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
this.sizeMode = value;
|
||||||
|
this.AutoScroll = (this.sizeMode == SizeMode.Scrollable);
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RatioStretch()
|
||||||
|
{
|
||||||
|
float pRatio = (float)this.Width / this.Height;
|
||||||
|
float imRatio = (float)this.pictureBox1.Image.Width / this.pictureBox1.Image.Height;
|
||||||
|
|
||||||
|
if (this.Width >= this.pictureBox1.Image.Width && this.Height >= this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.pictureBox1.Image.Width;
|
||||||
|
this.pictureBox1.Height = this.pictureBox1.Image.Height;
|
||||||
|
}
|
||||||
|
else if (this.Width > this.pictureBox1.Image.Width && this.Height < this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
else if (this.Width < this.pictureBox1.Image.Width && this.Height > this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
else if (this.Width < this.pictureBox1.Image.Width && this.Height < this.pictureBox1.Image.Height)
|
||||||
|
{
|
||||||
|
if (this.Width >= this.Height)
|
||||||
|
{
|
||||||
|
//width image
|
||||||
|
if (this.pictureBox1.Image.Width >= this.pictureBox1.Image.Height && imRatio >= pRatio)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//width image
|
||||||
|
if (this.pictureBox1.Image.Width < this.pictureBox1.Image.Height && imRatio < pRatio)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Height = this.Height;
|
||||||
|
this.pictureBox1.Width = (int)(this.Height * imRatio);
|
||||||
|
}
|
||||||
|
else // height image
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.Width;
|
||||||
|
this.pictureBox1.Height = (int)(this.Width / imRatio);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.CenterImage();
|
||||||
|
}
|
||||||
|
private void Scrollable()
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = this.pictureBox1.Image.Width;
|
||||||
|
this.pictureBox1.Height = this.pictureBox1.Image.Height;
|
||||||
|
this.CenterImage();
|
||||||
|
}
|
||||||
|
private void SetLayout()
|
||||||
|
{
|
||||||
|
if (this.pictureBox1.Image == null)
|
||||||
|
return;
|
||||||
|
if (this.sizeMode == SizeMode.RatioStretch)
|
||||||
|
this.RatioStretch();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.AutoScroll = false;
|
||||||
|
this.Scrollable();
|
||||||
|
this.AutoScroll = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void CenterImage()
|
||||||
|
{
|
||||||
|
int top = (int)((this.Height - this.pictureBox1.Height) / 2.0);
|
||||||
|
int left = (int)((this.Width - this.pictureBox1.Width) / 2.0);
|
||||||
|
if (top < 0)
|
||||||
|
top = 0;
|
||||||
|
if (left < 0)
|
||||||
|
left = 0;
|
||||||
|
this.pictureBox1.Top = top;
|
||||||
|
this.pictureBox1.Left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Component Designer generated code
|
||||||
|
/// <summary>
|
||||||
|
/// Required method for Designer support - do not modify
|
||||||
|
/// the contents of this method with the code editor.
|
||||||
|
/// </summary>
|
||||||
|
private void InitializeComponent()
|
||||||
|
{
|
||||||
|
this.pictureBox1 = new System.Windows.Forms.PictureBox();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// pictureBox1
|
||||||
|
//
|
||||||
|
this.pictureBox1.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.pictureBox1.Cursor = System.Windows.Forms.Cursors.Default;
|
||||||
|
this.pictureBox1.Location = new System.Drawing.Point(24, 32);
|
||||||
|
this.pictureBox1.Name = "pictureBox1";
|
||||||
|
this.pictureBox1.Size = new System.Drawing.Size(296, 208);
|
||||||
|
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||||
|
this.pictureBox1.TabIndex = 0;
|
||||||
|
this.pictureBox1.TabStop = false;
|
||||||
|
//
|
||||||
|
// Imagen
|
||||||
|
//
|
||||||
|
this.AutoScroll = true;
|
||||||
|
this.BackColor = System.Drawing.Color.Transparent;
|
||||||
|
this.Controls.Add(this.pictureBox1);
|
||||||
|
this.Name = "Imagen";
|
||||||
|
this.Size = new System.Drawing.Size(352, 272);
|
||||||
|
this.Load += new System.EventHandler(this.Viewer_Load);
|
||||||
|
this.Resize += new System.EventHandler(this.Viewer_Resize);
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private void Viewer_Load(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
this.pictureBox1.Width = 0;
|
||||||
|
this.pictureBox1.Height = 0;
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Viewer_Resize(object sender, System.EventArgs e)
|
||||||
|
{
|
||||||
|
this.SetLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
120
ucImagen.resx
Normal file
120
ucImagen.resx
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
<xsd:attribute ref="xml:space" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
Reference in New Issue
Block a user