replaced http://codereview.stackexchange.com/ with https://codereview.stackexchange.com/
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:
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:
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
}
}
Alain
- 472
- 1
- 4
- 17
Loading
lang-cs