timerobserver.cs

来自「Oracle Service Manager」· CS 代码 · 共 167 行

CS
167
字号
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
{
	/// <summary>
	/// 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.
	/// </summary>
	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();
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?