Skip to main content
Code Review

Return to Question

replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
Source Link
Tweeted twitter.com/#!/StackCodeReview/status/221870160494084097
Link to followup question.
Source Link
Alain
  • 472
  • 1
  • 4
  • 17

I am no attempting to implement the polling process using a Timer and the ThreadPool as recommended in the answer. A followup question has been posted here:

Timer to poll a Delegate


I am no attempting to implement the polling process using a Timer and the ThreadPool as recommended in the answer. A followup question has been posted here:

Timer to poll a Delegate

deleted 48 characters in body
Source Link
Alain
  • 472
  • 1
  • 4
  • 17
using System;
using System.Threading;
using System.Windows.Threading;
namespace FlagstoneRe.WPF.Utilities.Common
{
 /// <summary>This class allows a user to easily set up a seperate thread to poll some state,
 /// and set up an event that will fire if the state meets some condition.</summary>
 /// <typeparam name="T">The type of the value returned by the polling delegate.</typeparam>
 public class ConditionMonitor<T> : IDisposable
 {
 #region Private Properties
 private Object multiThreadLock = new Object();
 private Dispatcher originThread = null;
 private Thread monitorThread = null;
 private volatile bool Halted = false;
 #endregion
 #region Delegates
 /// <summary>A delegate provided by the user of this class which returns the current state,
 /// to be tested against a certain condition in the IsConditionMet delegate.</summary>
 public delegate T RequestState();
 public RequestState RequestStateDelegate { get; set; }
 /// <summary>A delegate provided by the user of this class which determines whether given the
 /// current state, the polling program should execute the ConditionMet delegate.</summary>
 public delegate bool IsConditionMet<T>IsConditionMet(T state);
 public IsConditionMet<T>IsConditionMet IsConditionMetDelegate { get; set; }
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorHandler<T>ConditionMonitorHandler(ConditionMonitor<T> source, T state);
 /// <summary>An event which fires each time the state is polled (use sparingly).</summary>
 public event ConditionMonitorHandler<T>ConditionMonitorHandler RequestReceived;
 /// <summary>An event which fires when the condition is met.</summary>
 public event ConditionMonitorHandler<T>ConditionMonitorHandler ConditionMet;
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorExceptionHandler<T>ConditionMonitorExceptionHandler(ConditionMonitor<T> source, T state, Exception ex);
 /// <summary>An event which fires if an exception is thrown while retrieving the state
 /// or testing whether the condition is met.</summary>
 public event ConditionMonitorExceptionHandler<T>ConditionMonitorExceptionHandler RequestError;
 #endregion
 #region Public Properties
 /// <summary>The time between requests made to the RequestStateDelegate. Default is 1 second (1000ms)</summary>
 public int PollInterval_Milliseconds { get; set; }
 /// <summary>Set to true to automatically halt polling once the condition is met. Default is False.</summary>
 public bool HaltWhenConditionMet { get; set; }
 #endregion
 #region Constructors
 /// <summary>Creates a new instance of a ConditionMonitor</summary>
 public ConditionMonitor()
 {
 originThread = Dispatcher.CurrentDispatcher;
 PollInterval_Milliseconds = (int)TimeSpan.FromSeconds(1).TotalMilliseconds;
 HaltWhenConditionMet = false;
 }
 #endregion
 #region Public Methods
 /// <summary>Begins polling the RequestStateDelegate on a seperate thread.</summary>
 public void BeginMonitoring()
 {
 if( RequestStateDelegate == null ) throw new Exception("No delegate specified for polling - please set the RequestStateDelegate property.");
 lock( multiThreadLock )
 {
 if( monitorThread != null ) throw new Exception("Previous monitoring has not yet been stopped!");
 monitorThread = new Thread(new ThreadStart(PollState));
 }
 Halted = false;
 monitorThread.Start();
 }
 /// <summary>Halts polling and ensures that no more requests will be made or events fired.</summary>
 public void StopMonitoring()
 {
 Halted = true;
 }
 /// <summary>Halts the thread if it is still running so that the instance can be garbage collected.</summary>
 public void IDisposable.Dispose()
 {
 StopMonitoring();
 }
 #endregion
 #region Private Methods
 /// <summary>Responsible for the polling loop and invoking events back on the origin thread.</summary>
 private void PollState()
 {
 while( !Halted )
 {
 T state = default(T);
 bool bConditionMet = false;
 try
 {
 state = RequestStateDelegate();
 InvokeEvent(RequestReceived, state);
 if( IsConditionMetDelegate != null && !Halted )
 {
 bConditionMet = IsConditionMetDelegate(state);
 if( bConditionMet )
 {
 InvokeEvent(ConditionMet, state);
 if( HaltWhenConditionMet ) Halted = true;
 }
 }
 }
 catch( Exception ex )
 {
 InvokeExceptionHandler(state, ex);
 }
 if( !Halted ) Thread.Sleep(PollInterval_Milliseconds);
 }
 monitorThread = null;
 }
 /// <summary>Invokes a delegate of type ConditionMonitorHandler on the origin thread.</summary>
 /// <param name="toInvoke">The delegate to invoke (RequestRecieved or ConditionMet)</param>
 /// <param name="state">The response from the last call to the RequestStateDelegate</param>
 private void InvokeEvent(ConditionMonitorHandler<T>ConditionMonitorHandler toInvoke, T state)
 {
 if( toInvoke != null && !Halted )
 originThread.BeginInvoke(toInvoke, new object[] { this, state });
 }
 /// <summary>Invokes the exception delegate on the origin thread.</summary>
 /// <param name="state">The response from the last call to the RequestStateDelegate, or null.</param>
 /// <param name="ex">The exception raised while calling the RequestStateDelegate or IsConditionMetDelegate.</param>
 private void InvokeExceptionHandler(T state, Exception ex)
 {
 if( RequestError != null && !Halted )
 originThread.BeginInvoke(RequestError, new object[] { this, state, ex });
 }
 #endregion
 }
}
using System;
using System.Threading;
using System.Windows.Threading;
namespace FlagstoneRe.WPF.Utilities.Common
{
 /// <summary>This class allows a user to easily set up a seperate thread to poll some state,
 /// and set up an event that will fire if the state meets some condition.</summary>
 /// <typeparam name="T">The type of the value returned by the polling delegate.</typeparam>
 public class ConditionMonitor<T> : IDisposable
 {
 #region Private Properties
 private Object multiThreadLock = new Object();
 private Dispatcher originThread = null;
 private Thread monitorThread = null;
 private volatile bool Halted = false;
 #endregion
 #region Delegates
 /// <summary>A delegate provided by the user of this class which returns the current state,
 /// to be tested against a certain condition in the IsConditionMet delegate.</summary>
 public delegate T RequestState();
 public RequestState RequestStateDelegate { get; set; }
 /// <summary>A delegate provided by the user of this class which determines whether given the
 /// current state, the polling program should execute the ConditionMet delegate.</summary>
 public delegate bool IsConditionMet<T>(T state);
 public IsConditionMet<T> IsConditionMetDelegate { get; set; }
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorHandler<T>(ConditionMonitor<T> source, T state);
 /// <summary>An event which fires each time the state is polled (use sparingly).</summary>
 public event ConditionMonitorHandler<T> RequestReceived;
 /// <summary>An event which fires when the condition is met.</summary>
 public event ConditionMonitorHandler<T> ConditionMet;
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorExceptionHandler<T>(ConditionMonitor<T> source, T state, Exception ex);
 /// <summary>An event which fires if an exception is thrown while retrieving the state
 /// or testing whether the condition is met.</summary>
 public event ConditionMonitorExceptionHandler<T> RequestError;
 #endregion
 #region Public Properties
 /// <summary>The time between requests made to the RequestStateDelegate. Default is 1 second (1000ms)</summary>
 public int PollInterval_Milliseconds { get; set; }
 /// <summary>Set to true to automatically halt polling once the condition is met. Default is False.</summary>
 public bool HaltWhenConditionMet { get; set; }
 #endregion
 #region Constructors
 /// <summary>Creates a new instance of a ConditionMonitor</summary>
 public ConditionMonitor()
 {
 originThread = Dispatcher.CurrentDispatcher;
 PollInterval_Milliseconds = (int)TimeSpan.FromSeconds(1).TotalMilliseconds;
 HaltWhenConditionMet = false;
 }
 #endregion
 #region Public Methods
 /// <summary>Begins polling the RequestStateDelegate on a seperate thread.</summary>
 public void BeginMonitoring()
 {
 if( RequestStateDelegate == null ) throw new Exception("No delegate specified for polling - please set the RequestStateDelegate property.");
 lock( multiThreadLock )
 {
 if( monitorThread != null ) throw new Exception("Previous monitoring has not yet been stopped!");
 monitorThread = new Thread(new ThreadStart(PollState));
 }
 Halted = false;
 monitorThread.Start();
 }
 /// <summary>Halts polling and ensures that no more requests will be made or events fired.</summary>
 public void StopMonitoring()
 {
 Halted = true;
 }
 /// <summary>Halts the thread if it is still running so that the instance can be garbage collected.</summary>
 public void IDisposable.Dispose()
 {
 StopMonitoring();
 }
 #endregion
 #region Private Methods
 /// <summary>Responsible for the polling loop and invoking events back on the origin thread.</summary>
 private void PollState()
 {
 while( !Halted )
 {
 T state = default(T);
 bool bConditionMet = false;
 try
 {
 state = RequestStateDelegate();
 InvokeEvent(RequestReceived, state);
 if( IsConditionMetDelegate != null && !Halted )
 {
 bConditionMet = IsConditionMetDelegate(state);
 if( bConditionMet )
 {
 InvokeEvent(ConditionMet, state);
 if( HaltWhenConditionMet ) Halted = true;
 }
 }
 }
 catch( Exception ex )
 {
 InvokeExceptionHandler(state, ex);
 }
 if( !Halted ) Thread.Sleep(PollInterval_Milliseconds);
 }
 monitorThread = null;
 }
 /// <summary>Invokes a delegate of type ConditionMonitorHandler on the origin thread.</summary>
 /// <param name="toInvoke">The delegate to invoke (RequestRecieved or ConditionMet)</param>
 /// <param name="state">The response from the last call to the RequestStateDelegate</param>
 private void InvokeEvent(ConditionMonitorHandler<T> toInvoke, T state)
 {
 if( toInvoke != null && !Halted )
 originThread.BeginInvoke(toInvoke, new object[] { this, state });
 }
 /// <summary>Invokes the exception delegate on the origin thread.</summary>
 /// <param name="state">The response from the last call to the RequestStateDelegate, or null.</param>
 /// <param name="ex">The exception raised while calling the RequestStateDelegate or IsConditionMetDelegate.</param>
 private void InvokeExceptionHandler(T state, Exception ex)
 {
 if( RequestError != null && !Halted )
 originThread.BeginInvoke(RequestError, new object[] { this, state, ex });
 }
 #endregion
 }
}
using System;
using System.Threading;
using System.Windows.Threading;
namespace WPF.Utilities.Common
{
 /// <summary>This class allows a user to easily set up a seperate thread to poll some state,
 /// and set up an event that will fire if the state meets some condition.</summary>
 /// <typeparam name="T">The type of the value returned by the polling delegate.</typeparam>
 public class ConditionMonitor<T> : IDisposable
 {
 #region Private Properties
 private Object multiThreadLock = new Object();
 private Dispatcher originThread = null;
 private Thread monitorThread = null;
 private volatile bool Halted = false;
 #endregion
 #region Delegates
 /// <summary>A delegate provided by the user of this class which returns the current state,
 /// to be tested against a certain condition in the IsConditionMet delegate.</summary>
 public delegate T RequestState();
 public RequestState RequestStateDelegate { get; set; }
 /// <summary>A delegate provided by the user of this class which determines whether given the
 /// current state, the polling program should execute the ConditionMet delegate.</summary>
 public delegate bool IsConditionMet(T state);
 public IsConditionMet IsConditionMetDelegate { get; set; }
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorHandler(ConditionMonitor<T> source, T state);
 /// <summary>An event which fires each time the state is polled (use sparingly).</summary>
 public event ConditionMonitorHandler RequestReceived;
 /// <summary>An event which fires when the condition is met.</summary>
 public event ConditionMonitorHandler ConditionMet;
 /// <summary>A delegate used to handle ConditionMonitor events.</summary>
 public delegate void ConditionMonitorExceptionHandler(ConditionMonitor<T> source, T state, Exception ex);
 /// <summary>An event which fires if an exception is thrown while retrieving the state
 /// or testing whether the condition is met.</summary>
 public event ConditionMonitorExceptionHandler RequestError;
 #endregion
 #region Public Properties
 /// <summary>The time between requests made to the RequestStateDelegate. Default is 1 second (1000ms)</summary>
 public int PollInterval_Milliseconds { get; set; }
 /// <summary>Set to true to automatically halt polling once the condition is met. Default is False.</summary>
 public bool HaltWhenConditionMet { get; set; }
 #endregion
 #region Constructors
 /// <summary>Creates a new instance of a ConditionMonitor</summary>
 public ConditionMonitor()
 {
 originThread = Dispatcher.CurrentDispatcher;
 PollInterval_Milliseconds = (int)TimeSpan.FromSeconds(1).TotalMilliseconds;
 HaltWhenConditionMet = false;
 }
 #endregion
 #region Public Methods
 /// <summary>Begins polling the RequestStateDelegate on a seperate thread.</summary>
 public void BeginMonitoring()
 {
 if( RequestStateDelegate == null ) throw new Exception("No delegate specified for polling - please set the RequestStateDelegate property.");
 lock( multiThreadLock )
 {
 if( monitorThread != null ) throw new Exception("Previous monitoring has not yet been stopped!");
 monitorThread = new Thread(new ThreadStart(PollState));
 }
 Halted = false;
 monitorThread.Start();
 }
 /// <summary>Halts polling and ensures that no more requests will be made or events fired.</summary>
 public void StopMonitoring()
 {
 Halted = true;
 }
 /// <summary>Halts the thread if it is still running so that the instance can be garbage collected.</summary>
 public void Dispose()
 {
 StopMonitoring();
 }
 #endregion
 #region Private Methods
 /// <summary>Responsible for the polling loop and invoking events back on the origin thread.</summary>
 private void PollState()
 {
 while( !Halted )
 {
 T state = default(T);
 bool bConditionMet = false;
 try
 {
 state = RequestStateDelegate();
 InvokeEvent(RequestReceived, state);
 if( IsConditionMetDelegate != null && !Halted )
 {
 bConditionMet = IsConditionMetDelegate(state);
 if( bConditionMet )
 {
 InvokeEvent(ConditionMet, state);
 if( HaltWhenConditionMet ) Halted = true;
 }
 }
 }
 catch( Exception ex )
 {
 InvokeExceptionHandler(state, ex);
 }
 if( !Halted ) Thread.Sleep(PollInterval_Milliseconds);
 }
 monitorThread = null;
 }
 /// <summary>Invokes a delegate of type ConditionMonitorHandler on the origin thread.</summary>
 /// <param name="toInvoke">The delegate to invoke (RequestRecieved or ConditionMet)</param>
 /// <param name="state">The response from the last call to the RequestStateDelegate</param>
 private void InvokeEvent(ConditionMonitorHandler toInvoke, T state)
 {
 if( toInvoke != null && !Halted )
 originThread.BeginInvoke(toInvoke, new object[] { this, state });
 }
 /// <summary>Invokes the exception delegate on the origin thread.</summary>
 /// <param name="state">The response from the last call to the RequestStateDelegate, or null.</param>
 /// <param name="ex">The exception raised while calling the RequestStateDelegate or IsConditionMetDelegate.</param>
 private void InvokeExceptionHandler(T state, Exception ex)
 {
 if( RequestError != null && !Halted )
 originThread.BeginInvoke(RequestError, new object[] { this, state, ex });
 }
 #endregion
 }
}
Adding revised code
Source Link
Alain
  • 472
  • 1
  • 4
  • 17
Loading
edited to include full code, because we don't like pastebin links here.
Source Link
Alain
  • 472
  • 1
  • 4
  • 17
Loading
added 8 characters in body
Source Link
Alain
  • 472
  • 1
  • 4
  • 17
Loading
Source Link
Alain
  • 472
  • 1
  • 4
  • 17
Loading
lang-cs

AltStyle によって変換されたページ (->オリジナル) /