Hi,
I have implemented the Change() method[ false return value ) and the Dispose()
method, which was incomplete.
Please inform me whether this is fine or it needs any other modification.
I will be interested to complete all the TODOs in the �System.Threading� namespace.
P.S: Timer.cs
Regards,
Deepak.
//
// System.Threading.Timer.cs
//
// Authors:
// Dick Porter ([EMAIL PROTECTED])
// Gonzalo Paniagua Javier ([EMAIL PROTECTED])
//
// (C) 2001, 2002 Ximian, Inc. http://www.ximian.com
//
using System.Collections;
namespace System.Threading
{
public sealed class Timer : MarshalByRefObject, IDisposable
{
// A Static ArrayList which holds all references to active timers
private static ArrayList arrayList = new ArrayList();
sealed class Runner : MarshalByRefObject, IDisposable
{
ManualResetEvent wait;
AutoResetEvent start_event;
TimerCallback callback;
object state;
int dueTime;
int period;
bool disposed;
bool aborted;
public Runner (TimerCallback callback, object state,
AutoResetEvent start_event)
{
this.callback = callback;
this.state = state;
this.start_event = start_event;
this.wait = new ManualResetEvent (false);
}
public int DueTime {
get { return dueTime; }
set { dueTime = value; }
}
public int Period {
get { return period; }
set { period = value == 0 ? Timeout.Infinite : value; }
}
bool WaitForDueTime ()
{
if (dueTime > 0) {
bool signaled;
do {
wait.Reset ();
signaled = wait.WaitOne (dueTime,
false);
} while (signaled == true && !disposed &&
!aborted);
if (!signaled)
callback (state);
if (disposed)
return false;
}
return true;
}
public void Abort ()
{
lock (this) {
aborted = true;
wait.Set ();
}
}
public void Start ()
{
while (start_event.WaitOne ()) {
aborted = false;
if (dueTime == Timeout.Infinite)
continue;
if (!WaitForDueTime ())
return;
if (aborted || (period == Timeout.Infinite))
continue;
bool signaled = false;
while (true) {
if (disposed)
return;
if (aborted)
break;
wait.Reset ();
signaled = wait.WaitOne (period,
false);
if (!signaled) {
callback (state);
} else if (!WaitForDueTime ()) {
return;
}
}
}
}
public void Dispose ()
{
Dispose (true);
}
void Dispose (bool disposing)
{
// Remove the current object from the arrayList
arrayList.Remove( this );
disposed = true;
if (wait != null) {
wait.Set ();
Thread.Sleep (100);
((IDisposable) wait).Dispose ();
wait = null;
}
if (disposing)
GC.SuppressFinalize (this);
}
~Runner ()
{
Dispose (false);
}
}
Runner runner;
AutoResetEvent start_event;
public Timer (TimerCallback callback, object state, int dueTime, int
period)
{
if (dueTime < -1)
throw new ArgumentOutOfRangeException ("dueTime");
if (period < -1)
throw new ArgumentOutOfRangeException ("period");
Init (callback, state, dueTime, period);
}
public Timer (TimerCallback callback, object state, long dueTime, long
period)
{
if (dueTime < -1)
throw new ArgumentOutOfRangeException ("dueTime");
if (period < -1)
throw new ArgumentOutOfRangeException ("period");
Init (callback, state, (int) dueTime, (int) period);
}
public Timer (TimerCallback callback, object state, TimeSpan dueTime,
TimeSpan period)
: this (callback, state,
Convert.ToInt32(dueTime.TotalMilliseconds), Convert.ToInt32(period.TotalMilliseconds))
{
}
[CLSCompliant(false)]
public Timer (TimerCallback callback, object state, uint dueTime, uint
period)
: this (callback, state, (long) dueTime, (long) period)
{
}
void Init (TimerCallback callback, object state, int dueTime, int
period)
{
// An instance of the Timer class is generated - Add this to
ArrayList
arrayList.Add( this );
start_event = new AutoResetEvent (false);
runner = new Runner (callback, state, start_event);
Change (dueTime, period);
Thread t = new Thread (new ThreadStart (runner.Start));
t.IsBackground = true;
t.Start ();
}
//[MonoTODO("false return?")]
public bool Change (int dueTime, int period)
{
if (dueTime < -1)
throw new ArgumentOutOfRangeException ("dueTime");
if (period < -1)
throw new ArgumentOutOfRangeException ("period");
if( !arrayList.Contains( this ) )
{
return( false );
}
runner.DueTime = dueTime;
runner.Period = period;
runner.Abort ();
start_event.Set ();
return true;
}
public bool Change (long dueTime, long period)
{
if(dueTime > 4294967294)
throw new NotSupportedException ("Due time too large");
if(period > 4294967294)
throw new NotSupportedException ("Period too large");
return Change ((int) dueTime, (int) period);
}
public bool Change (TimeSpan dueTime, TimeSpan period)
{
return Change (Convert.ToInt32(dueTime.TotalMilliseconds),
Convert.ToInt32(period.TotalMilliseconds));
}
[CLSCompliant(false)]
public bool Change (uint dueTime, uint period)
{
if (dueTime > Int32.MaxValue)
throw new NotSupportedException ("Due time too large");
if (period > Int32.MaxValue)
throw new NotSupportedException ("Period too large");
return Change ((int) dueTime, (int) period);
}
public void Dispose ()
{
runner.Dispose ();
runner = null;
GC.SuppressFinalize (this);
}
//[MonoTODO("How to know the number of times the WaitOne() is called
on Mutex?")]
public bool Dispose (WaitHandle notifyObject)
{
Dispose ();
if( notifyObject is AutoResetEvent )
{
AutoResetEvent ae = ( AutoResetEvent ) notifyObject;
ae.Set();
}
else if ( notifyObject is ManualResetEvent )
{
ManualResetEvent me = ( ManualResetEvent )
notifyObject;
me.Set();
}
else if ( notifyObject is Mutex )
{
Mutex mutexEvent = ( Mutex ) notifyObject;
mutexEvent.ReleaseMutex(); //FIXME
}
return true;
}
~Timer ()
{
runner = null;
}
}
}