www.pudn.com > OracleServiceManager.zip > TimerObserver.cs
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using kae.ServiceStatePublisher;
namespace kae.OracleServiceManager
{
///
/// TimerObserver is a concrete observer listening to the current subject for changes.
/// TimerObserver uses a system timer to periodically check for changes made outside OSM.
///
public class TimerObserver
{
private delegate void ChangeStateCallback( ServiceState state);
private System.Timers.Timer _timer;
private DateTime _stopTime;
private ServiceState _state;
private ISynchronizeInvoke _syncObject;
private ChangeStateCallback changeStateCallback;
private int _uiThreadId;
public TimerObserver( ServiceSubject subject, double interval) : this( subject, interval, null)
{
}
public TimerObserver( ServiceSubject subject, double interval, ISynchronizeInvoke synchronizingObject)
{
InitializeDebugInfo( "UIThread");
Debug.WriteLine( String.Format( "UIThreadId = {0}", _uiThreadId));
if (subject != null)
{
subject.ServerChanged += new EventHandler( this.OnServerChanged);
subject.ServiceChanged += new EventHandler( this.OnServiceChanged);
subject.StateChanged += new EventHandler( this.OnStateChanged);
}
_timer = new System.Timers.Timer( interval);
_timer.Elapsed += new ElapsedEventHandler( this.OnTimerElapsed);
SynchronizingObject = synchronizingObject;
changeStateCallback = new ChangeStateCallback( this.ChangeState);
}
public void Dispose()
{
StopTimer();
_timer.Dispose();
_timer = null;
}
#region Debug Stuff
[Conditional("DEBUG")]
private void InitializeDebugInfo( string name)
{
Thread.CurrentThread.Name = "UIThread";
_uiThreadId = AppDomain.GetCurrentThreadId();
}
[Conditional("DEBUG")]
private void WriteThreadDebugInfo( string methodName)
{
string threadName = (AppDomain.GetCurrentThreadId() != _uiThreadId) ? "WorkerThread" : Thread.CurrentThread.Name;
Debug.WriteLine( String.Format( "{0}[{1}:{2}]", methodName, AppDomain.GetCurrentThreadId(), threadName));
}
#endregion
internal ServiceState State
{
get { return _state; }
set { _state = value; }
}
private ISynchronizeInvoke SynchronizingObject
{
get { return _syncObject; }
set { _syncObject = value; }
}
public double Interval
{
get { return _timer.Interval; }
set { _timer.Interval = value; }
}
internal DateTime StopTime
{
get { return _stopTime; }
set { _stopTime = value; }
}
private void OnTimerElapsed( object sender, ElapsedEventArgs e)
{
Debug.WriteLine( String.Format("OnTimerElapsed fired at {0}", e.SignalTime));
if (e.SignalTime < StopTime)
{
ServiceSubject subject = OracleServiceManager.Instance.Subject;
ServiceController service = new ServiceController( subject.Controller.ServiceName, subject.ServerName);
ServiceContext context = new ServiceContext( service);
WriteThreadDebugInfo( "OnTimerElapsed");
if (State.GetType() != context.State.GetType())
{
Debug.WriteLine( String.Format("State = {0}\ncontext.State = {1}", State.GetType(), context.State.GetType()));
object[] stateArray = new object[] { context.State };
if (SynchronizingObject != null)
SynchronizingObject.BeginInvoke( changeStateCallback, stateArray);
else
ChangeState( context.State);
}
}
}
private void ChangeState( ServiceState state)
{
WriteThreadDebugInfo( "ChangeState");
OracleServiceManager.Instance.Subject.State = state;
}
private void OnServerChanged( object sender, EventArgs e)
{
ServiceSubject subject = (ServiceSubject) sender;
StopTimer();
State = subject.State;
}
private void OnServiceChanged( object sender, EventArgs e)
{
ServiceSubject subject = (ServiceSubject) sender;
State = subject.State;
StopTimer();
if (subject.Controller != null)
StartTimer();
}
private void OnStateChanged( object sender, EventArgs e)
{
ServiceSubject subject = (ServiceSubject) sender;
State = subject.State;
}
private void StopTimer()
{
StopTime = DateTime.Now;
_timer.Stop();
}
private void StartTimer()
{
StopTime = DateTime.MaxValue;
_timer.Start();
}
}
}