initial checkin of yaulw (locally)
This commit is contained in:
507
Thread/DispatcherThread.cs
Normal file
507
Thread/DispatcherThread.cs
Normal file
@@ -0,0 +1,507 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Sys = System.Threading;
|
||||
using System.Reflection;
|
||||
using Yaulw.WPF;
|
||||
using System.Threading;
|
||||
using System.Windows.Threading;
|
||||
using Yaulw.Other;
|
||||
|
||||
namespace Yaulw.Thread
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public enum DispatcherThreatType
|
||||
{
|
||||
WPF,
|
||||
// Winforms // ~Not implmented
|
||||
// Silverlight? // ~Not implemented
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class WindowType
|
||||
{
|
||||
public Type T;
|
||||
public Enum Key;
|
||||
public bool IsSingleton;
|
||||
public bool IsPerformanceLoaded;
|
||||
|
||||
public WindowType(Type t, Enum Key, bool IsSingleton, bool IsPerformanceLoaded)
|
||||
{
|
||||
this.T = t;
|
||||
this.Key = Key;
|
||||
this.IsSingleton = IsSingleton;
|
||||
this.IsPerformanceLoaded = IsPerformanceLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class WindowAttributes
|
||||
{
|
||||
public IntPtr hWndOwner;
|
||||
public uint Height;
|
||||
public uint Width;
|
||||
public int Top;
|
||||
public int Left;
|
||||
public string Title;
|
||||
|
||||
public WindowAttributes(IntPtr hWndOwner, uint Height, uint Width, int Top, int Left, string Title)
|
||||
{
|
||||
this.hWndOwner = hWndOwner;
|
||||
this.Height = Height;
|
||||
this.Width = Width;
|
||||
this.Top = Top;
|
||||
this.Left = Left;
|
||||
this.Title = Title;
|
||||
}
|
||||
|
||||
public WindowAttributes(IntPtr hWndOwner, int Top, int Left)
|
||||
{
|
||||
this.hWndOwner = hWndOwner;
|
||||
this.Height = 0;
|
||||
this.Width = 0;
|
||||
this.Top = Top;
|
||||
this.Left = Left;
|
||||
this.Title = String.Empty;
|
||||
}
|
||||
|
||||
public WindowAttributes(IntPtr hWndOwner)
|
||||
{
|
||||
this.hWndOwner = hWndOwner;
|
||||
this.Height = 0;
|
||||
this.Width = 0;
|
||||
this.Top = int.MinValue;
|
||||
this.Left = int.MinValue;
|
||||
this.Title = String.Empty;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#region Window Manager Definition
|
||||
|
||||
/// <summary>
|
||||
/// Abstract Base Class all Window Managers must inherit from.
|
||||
///
|
||||
/// </summary>
|
||||
public abstract class WindowManager : IDisposable
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private Dictionary<WindowType, List<object>> s_WindowsToManage = new Dictionary<WindowType, List<object>>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Construct a Window Manager Object
|
||||
/// </summary>
|
||||
/// <param name="dispatcher">Thread Dispatcher Object</param>
|
||||
/// <param name="windowTypes">Window Types this WindowManager is managing</param>
|
||||
/// <param name="PerformanceLoad">true, to load performance enabled windows upon construction</param>
|
||||
public WindowManager(Dispatcher dispatcher, WindowType[] windowTypes, bool PerformanceLoad)
|
||||
{
|
||||
Dispatcher = dispatcher;
|
||||
WindowTypes = windowTypes;
|
||||
if (Dispatcher == null)
|
||||
throw new ArgumentException("dispatcher can't be null");
|
||||
if (windowTypes == null || windowTypes.Length < 1)
|
||||
throw new ArgumentException("windowTypes can't be null or empty");
|
||||
|
||||
// Add All Window Types
|
||||
foreach (WindowType type in windowTypes)
|
||||
{
|
||||
// Add the Type to be managed
|
||||
AddWindowTypeToManage(type);
|
||||
|
||||
// perform performance optimization
|
||||
if (PerformanceLoad && type.IsPerformanceLoaded)
|
||||
{
|
||||
object o = CreateInstance(type);
|
||||
AddObject(type, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Properties
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Dispatcher Thread responsible for this Window Manager
|
||||
/// </summary>
|
||||
public Dispatcher Dispatcher { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all the Window Types that have been set to be managed by this Window Manager
|
||||
/// </summary>
|
||||
public WindowType[] WindowTypes { get; private set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Common Window Object Operations
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Object Instance of type
|
||||
/// </summary>
|
||||
/// <param name="window">type of object to create</param>
|
||||
/// <returns>a new object for type, or null</returns>
|
||||
protected object CreateInstance(WindowType window)
|
||||
{
|
||||
object o = null;
|
||||
if (window != null)
|
||||
o = Activator.CreateInstance(window.T);
|
||||
return o;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new Object Instance of type
|
||||
/// </summary>
|
||||
/// <param name="windowKey">type of object to create</param>
|
||||
/// <returns>a new object for type, or null</returns>
|
||||
protected object CreateInstance(Enum windowKey)
|
||||
{
|
||||
return CreateInstance(GetType(windowKey));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="windowKey"></param>
|
||||
/// <returns></returns>
|
||||
protected List<object> GetObjects(Enum windowKey)
|
||||
{
|
||||
foreach (WindowType type in s_WindowsToManage.Keys)
|
||||
{
|
||||
if (type.Key.ToString() == windowKey.ToString())
|
||||
return s_WindowsToManage[type];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
/// <returns></returns>
|
||||
protected List<object> GetObjects(WindowType window)
|
||||
{
|
||||
foreach (WindowType type in s_WindowsToManage.Keys)
|
||||
{
|
||||
if (type.Key.ToString() == window.Key.ToString())
|
||||
return s_WindowsToManage[type];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="windowKey"></param>
|
||||
/// <returns></returns>
|
||||
protected WindowType GetType(Enum windowKey)
|
||||
{
|
||||
foreach (WindowType type in s_WindowsToManage.Keys)
|
||||
{
|
||||
if (type.Key.ToString() == windowKey.ToString())
|
||||
return type;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
protected bool AddObject(WindowType window, object o)
|
||||
{
|
||||
if (AddWindowTypeToManage(window))
|
||||
{
|
||||
List<object> objects = GetObjects(window);
|
||||
if (objects.Count == 0)
|
||||
{
|
||||
objects.Add(o);
|
||||
return true;
|
||||
}
|
||||
else if (objects.Count > 0 && !window.IsSingleton)
|
||||
{
|
||||
objects.Add(o);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="windowKey"></param>
|
||||
/// <param name="o"></param>
|
||||
/// <returns></returns>
|
||||
protected bool AddObject(Enum windowKey, object o)
|
||||
{
|
||||
WindowType type = GetType(windowKey);
|
||||
if (type != null)
|
||||
{
|
||||
List<object> objects = GetObjects(windowKey);
|
||||
if (objects.Count == 0)
|
||||
{
|
||||
objects.Add(o);
|
||||
return true;
|
||||
}
|
||||
else if (objects.Count > 0 && !type.IsSingleton)
|
||||
{
|
||||
objects.Add(o);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
/// <returns></returns>
|
||||
protected bool DeleteObject(WindowType window)
|
||||
{
|
||||
List<object> objects = GetObjects(window);
|
||||
if (objects != null && objects.Count > 0)
|
||||
{
|
||||
int nIndex = objects.Count - 1;
|
||||
if (objects[nIndex] is IDisposable)
|
||||
((IDisposable)objects[nIndex]).Dispose();
|
||||
objects.RemoveAt(nIndex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="windowKey"></param>
|
||||
/// <returns></returns>
|
||||
protected bool DeleteObject(Enum windowKey)
|
||||
{
|
||||
List<object> objects = GetObjects(windowKey);
|
||||
if (objects != null && objects.Count > 0)
|
||||
{
|
||||
int nIndex = objects.Count - 1;
|
||||
if (objects[nIndex] is IDisposable)
|
||||
((IDisposable)objects[nIndex]).Dispose();
|
||||
objects.RemoveAt(nIndex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
protected void ClearAllObjects()
|
||||
{
|
||||
// Iterate thru all objects and call dispose on them if they support it,
|
||||
// then clear main dictionary
|
||||
foreach (WindowType type in s_WindowsToManage.Keys)
|
||||
while (DeleteObject(type)) ;
|
||||
|
||||
s_WindowsToManage.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
/// <returns></returns>
|
||||
protected bool AddWindowTypeToManage(WindowType window)
|
||||
{
|
||||
if (window != null && !IsWindowTypeManaged(window))
|
||||
s_WindowsToManage[window] = new List<object>();
|
||||
|
||||
return (IsWindowTypeManaged(window));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="window"></param>
|
||||
/// <returns></returns>
|
||||
protected bool IsWindowTypeManaged(WindowType window)
|
||||
{
|
||||
if (window != null)
|
||||
{
|
||||
foreach (WindowType type in s_WindowsToManage.Keys)
|
||||
{
|
||||
if (type.Key.ToString() == window.Key.ToString())
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Abtract Methods
|
||||
|
||||
public delegate object ShowDelegate(Enum windowKey, WindowAttributes attributes, object tag);
|
||||
public abstract object ShowWindow(Enum windowKey, WindowAttributes attributes, object tag);
|
||||
public abstract object ShowDialog(Enum windowKey, WindowAttributes attributes, object tag);
|
||||
|
||||
public delegate bool HideCloseDelegate(Enum windowKey);
|
||||
public abstract bool HideWindow(Enum windowKey);
|
||||
public abstract bool CloseWindow(Enum windowKey);
|
||||
|
||||
public delegate bool ActionDelegate(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
|
||||
public abstract bool RunAction(Enum windowKey, DelegateCollection.Bool_Param1_Window_Func action);
|
||||
|
||||
public abstract void Dispose();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Get All Window Objects for a Window, in a readonly fashion
|
||||
/// </summary>
|
||||
/// <param name="windowKey"></param>
|
||||
/// <returns></returns>
|
||||
public object[] GetAllWindowObjectsForWindow(Enum windowKey)
|
||||
{
|
||||
List<object> objects = GetObjects(windowKey);
|
||||
if (objects != null)
|
||||
return objects.ToArray();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Dispatcher Thread
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
static class DispatcherThread
|
||||
{
|
||||
#region Private Static Members
|
||||
|
||||
private static Sys.Thread s_DispatcherThread = null;
|
||||
private static bool s_DispatcherThreadIsInitialized = false;
|
||||
|
||||
private static WPFWindowManager s_wpfWindowManager = null;
|
||||
private static DispatcherThreatType s_useWindowManagerType = DispatcherThreatType.WPF;
|
||||
private static WindowType[] s_windowTypes = null;
|
||||
private static bool s_PerformPerformanceLoad = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// Message Loop Thread for ButtonForm
|
||||
/// </summary>
|
||||
private static void ThreadProc()
|
||||
{
|
||||
// Create WindowManager Object on this thread *Allow global access to the object*
|
||||
if (s_useWindowManagerType == DispatcherThreatType.WPF)
|
||||
s_wpfWindowManager = new WPFWindowManager(Dispatcher.CurrentDispatcher, s_windowTypes, s_PerformPerformanceLoad);
|
||||
|
||||
s_DispatcherThreadIsInitialized = true; // always set to true to allow caller to exit out
|
||||
if (s_wpfWindowManager != null)
|
||||
{
|
||||
//Enter Dispatcher Message Loop
|
||||
System.Windows.Threading.Dispatcher.Run();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Static Methods
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve the Window Manager for this Dispatcher Thread
|
||||
/// </summary>
|
||||
/// <returns>a valid window Manager or null, if none</returns>
|
||||
public static WindowManager GetWMForDispatcher()
|
||||
{
|
||||
if (s_DispatcherThreadIsInitialized)
|
||||
{
|
||||
if (s_useWindowManagerType == DispatcherThreatType.WPF && s_wpfWindowManager != null)
|
||||
return s_wpfWindowManager;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to start the Dispatcher ThreadProc(above), if needed. COM+ can shutdown the thread anytime,
|
||||
/// we need to make sure that the thread is alive BEFORE calling WindowManager
|
||||
/// </summary>
|
||||
public static void Start(DispatcherThreatType threatType, WindowType[] windowTypes, bool PerformPerformanceLoad, bool bWait)
|
||||
{
|
||||
if (s_DispatcherThread != null && s_DispatcherThread.IsAlive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_DispatcherThreadIsInitialized = false;
|
||||
|
||||
// Specify Thread Attributes
|
||||
s_useWindowManagerType = threatType;
|
||||
s_windowTypes = windowTypes;
|
||||
s_PerformPerformanceLoad = PerformPerformanceLoad;
|
||||
|
||||
// Start a new Thread so it can become the Message Loop
|
||||
s_DispatcherThread = new Sys.Thread(new Sys.ThreadStart(DispatcherThread.ThreadProc));
|
||||
|
||||
// GUI components require the thread to be STA; otherwise throws an error
|
||||
s_DispatcherThread.SetApartmentState(ApartmentState.STA);
|
||||
s_DispatcherThread.Start();
|
||||
|
||||
// Make sure the Application Object is running
|
||||
// (COM will eventually just time out otherwise)
|
||||
if (bWait) // Syncronous call
|
||||
{
|
||||
while (!s_DispatcherThreadIsInitialized)
|
||||
System.Threading.Thread.Sleep(20);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Terminates all ButtonForm Objects and the Message Dispatcher Thread *do this only on shutdown*
|
||||
/// </summary>
|
||||
public static void Stop()
|
||||
{
|
||||
if (s_DispatcherThreadIsInitialized)
|
||||
{
|
||||
// Enforce that all WindowManagers support IDispose
|
||||
if (s_wpfWindowManager != null)
|
||||
{
|
||||
s_wpfWindowManager.Dispose();
|
||||
s_wpfWindowManager = null;
|
||||
}
|
||||
s_DispatcherThread.Abort();
|
||||
s_DispatcherThreadIsInitialized = false;
|
||||
s_DispatcherThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
143
Thread/SingleThreadTimer.cs
Normal file
143
Thread/SingleThreadTimer.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
|
||||
namespace Yaulw.Thread
|
||||
{
|
||||
/// <summary>
|
||||
/// Single Threaded Timer * only calls the elapsed event handler once and only
|
||||
/// will call it again, if the elapsed event handler returns
|
||||
/// </summary>
|
||||
public class SingleThreadTimer
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private STElapsedEventHandler _elapsedHandler = null;
|
||||
private uint _IntervalMilliseconds = 0;
|
||||
private System.Threading.Thread _thread = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Single-threaded System.Timer
|
||||
/// </summary>
|
||||
/// <param name="ElapsedHandler">Event Handler for Timer</param>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
|
||||
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
|
||||
public SingleThreadTimer(STElapsedEventHandler ElapsedHandler, uint IntervalMilliseconds, bool StartEnabled)
|
||||
{
|
||||
_elapsedHandler = ElapsedHandler;
|
||||
_IntervalMilliseconds = IntervalMilliseconds;
|
||||
if (_elapsedHandler == null || _IntervalMilliseconds == 0)
|
||||
throw new ArgumentException("Invalid ElapsedHandler or Milliseconds. ElapsedHandler can not be null. Milliseconds can not be 0.");
|
||||
|
||||
if (StartEnabled)
|
||||
Start();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
/// <summary>
|
||||
/// Main DoWork() Function, calls the ElapsedHandler at every interval
|
||||
/// * Single threaded * ElapsedHandler will only get called again, once it returns
|
||||
/// </summary>
|
||||
private void STimerThreadMethod()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (_IntervalMilliseconds > 0)
|
||||
System.Threading.Thread.Sleep((int)_IntervalMilliseconds);
|
||||
|
||||
if (_elapsedHandler != null)
|
||||
_elapsedHandler(this, new STElapsedEventArgs(DateTime.Now));
|
||||
}
|
||||
while (true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Delegates
|
||||
|
||||
/// <summary>
|
||||
/// ElapsedEvent Handler is called when the time interval elapsed
|
||||
/// </summary>
|
||||
/// <param name="sender">Sends the STimer Object</param>
|
||||
/// <param name="e">sends the Timestampe when the interval elapsed</param>
|
||||
public delegate void STElapsedEventHandler(object sender, STElapsedEventArgs e);
|
||||
|
||||
/// <summary>
|
||||
/// ElapsedEventArgs are called with the time stamp when the Event was raised
|
||||
/// </summary>
|
||||
public class STElapsedEventArgs : EventArgs
|
||||
{
|
||||
public DateTime SignalTime { get; private set; }
|
||||
public STElapsedEventArgs(DateTime SignalTime) { this.SignalTime = SignalTime; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the STimer
|
||||
/// </summary>
|
||||
public bool Start()
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
return Start(_IntervalMilliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the STimer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="tsInterval">Interval as a TimeSpan</param>
|
||||
public bool Start(TimeSpan tsInterval)
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
return Start((uint)tsInterval.TotalMilliseconds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the STimer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
public bool Start(uint IntervalMiliseconds)
|
||||
{
|
||||
try
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
if (IntervalMiliseconds > 0)
|
||||
_IntervalMilliseconds = IntervalMiliseconds;
|
||||
if (_thread == null)
|
||||
_thread = TStarter.StartThread(STimerThreadMethod, ("STimer-" + _elapsedHandler.Method.Name), System.Threading.ApartmentState.MTA, false, System.Threading.ThreadPriority.Normal);
|
||||
return ((_thread != null) && (_thread.IsAlive));
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Stop the STimer
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_thread != null)
|
||||
_thread.Abort();
|
||||
}
|
||||
catch (Exception) { /* ignore */ }
|
||||
_thread = null;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
140
Thread/TStarter.cs
Normal file
140
Thread/TStarter.cs
Normal file
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Yaulw.Thread
|
||||
{
|
||||
/// <remarks>
|
||||
/// Used to Manage/Launch Threads In an Application
|
||||
/// </remarks>
|
||||
public static class TStarter
|
||||
{
|
||||
#region Public Delegates
|
||||
|
||||
/// <summary>
|
||||
/// Thread Delegate with a single Object as a parameter
|
||||
/// </summary>
|
||||
/// <param name="o">object to be passed to Delegate</param>
|
||||
public delegate void ParameterizedThreadMethod(object o);
|
||||
|
||||
/// <summary>
|
||||
/// No Parameter Thread Delegate
|
||||
/// </summary>
|
||||
public delegate void ThreadMethod();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Static Members
|
||||
|
||||
private static Dictionary<string, System.Threading.Thread> _StartedNamedThreads = new Dictionary<string, System.Threading.Thread>();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Statics
|
||||
|
||||
/// <summary>
|
||||
/// Starts a Parameterized thread
|
||||
/// </summary>
|
||||
/// <param name="method">specifcy a method to invoke</param>
|
||||
/// <param name="parameter">specify a parameter to pass to the method</param>
|
||||
/// <param name="threadName">If you specify a ThreadName, it must be Unique to the Application</param>
|
||||
/// <param name="Apartment">ApartmentState</param>
|
||||
/// <param name="IsBackground">Is Background Thread</param>
|
||||
/// <param name="priority">set thread priority</param>
|
||||
/// <returns>a thread object if successful, null otherwise</returns>
|
||||
public static System.Threading.Thread StartParameterizedThread(ParameterizedThreadMethod method, object parameter, string threadName = "", ApartmentState Apartment = ApartmentState.MTA, bool IsBackground = false, ThreadPriority priority = ThreadPriority.Normal)
|
||||
{
|
||||
// If a threadName is defined, make sure that it is unique to the application
|
||||
if (!String.IsNullOrEmpty(threadName) && _StartedNamedThreads.ContainsKey(threadName))
|
||||
return null;
|
||||
|
||||
System.Threading.Thread thread = null;
|
||||
if (method != null && parameter != null)
|
||||
{
|
||||
thread = new System.Threading.Thread(new ParameterizedThreadStart(method));
|
||||
if (!String.IsNullOrEmpty(threadName))
|
||||
thread.Name = threadName;
|
||||
|
||||
// Start the Thread
|
||||
thread.SetApartmentState(Apartment);
|
||||
thread.Priority = priority;
|
||||
thread.IsBackground = IsBackground;
|
||||
thread.Start(parameter);
|
||||
|
||||
// Save the Thread in the Dictionary
|
||||
if (!String.IsNullOrEmpty(threadName))
|
||||
_StartedNamedThreads[threadName] = thread;
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts a thread without Parameters
|
||||
/// </summary>
|
||||
/// <param name="method">specifcy a method to invoke</param>
|
||||
/// <param name="threadName">If you specify a ThreadName, it must be Unique to the Application</param>
|
||||
/// <param name="Apartment">ApartmentState</param>
|
||||
/// <param name="IsBackground">Is Background Thread</param>
|
||||
/// <param name="priority">set thread priority</param>
|
||||
/// <returns>a thread object if successful, null otherwise</returns>
|
||||
public static System.Threading.Thread StartThread(ThreadMethod method, string threadName = "", ApartmentState Apartment = ApartmentState.MTA, bool IsBackground = false, ThreadPriority priority = ThreadPriority.Normal)
|
||||
{
|
||||
// If a threadName is defined, make sure that it is unique to the system
|
||||
if (!String.IsNullOrEmpty(threadName) && _StartedNamedThreads.ContainsKey(threadName))
|
||||
return null;
|
||||
|
||||
System.Threading.Thread thread = null;
|
||||
if (method != null)
|
||||
{
|
||||
thread = new System.Threading.Thread(new ThreadStart(method));
|
||||
if (!String.IsNullOrEmpty(threadName))
|
||||
thread.Name = threadName;
|
||||
|
||||
// Start the Thread
|
||||
thread.SetApartmentState(Apartment);
|
||||
thread.Priority = priority;
|
||||
thread.IsBackground = IsBackground;
|
||||
thread.Start();
|
||||
|
||||
// Save the Thread in the Dictionary
|
||||
if (!String.IsNullOrEmpty(threadName))
|
||||
_StartedNamedThreads[threadName] = thread;
|
||||
}
|
||||
return thread;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieve all Named threads that were started thru here that are still running
|
||||
/// </summary>
|
||||
/// <returns>an array of running named threads, null if none</returns>
|
||||
public static System.Threading.Thread[] GetStartedNamedThreadsThatAreStillRunning()
|
||||
{
|
||||
List<System.Threading.Thread> threads = new List<System.Threading.Thread>();
|
||||
List<string> threadNamesThatAreNoLongerAlive = new List<string>();
|
||||
|
||||
// Get Named Alive Threads
|
||||
foreach (System.Threading.Thread thread in _StartedNamedThreads.Values)
|
||||
{
|
||||
if (thread.IsAlive)
|
||||
threads.Add(thread);
|
||||
else
|
||||
threadNamesThatAreNoLongerAlive.Add(thread.Name);
|
||||
}
|
||||
|
||||
// Perform Cleanup
|
||||
foreach (string threadName in threadNamesThatAreNoLongerAlive)
|
||||
{
|
||||
_StartedNamedThreads[threadName] = null;
|
||||
_StartedNamedThreads.Remove(threadName);
|
||||
}
|
||||
|
||||
return threads.ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
143
Thread/TTimer.cs
Normal file
143
Thread/TTimer.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
using System.Windows.Threading;
|
||||
using WinThread = System.Threading;
|
||||
|
||||
namespace Yaulw.Thread
|
||||
{
|
||||
/// <remarks>
|
||||
/// Wrapper class around Timer Object * Multi-Threated *
|
||||
/// </remarks>
|
||||
public class TTimer : IDisposable
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private Timer _Timer = new Timer();
|
||||
private bool _disposed = false;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Multi-threaded System.Timer
|
||||
/// </summary>
|
||||
/// <param name="ElapsedHandler">Event Handler for Timer</param>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
|
||||
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
|
||||
public TTimer(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds = 1000, bool StartEnabled = false)
|
||||
{
|
||||
if (ElapsedHandler != null)
|
||||
{
|
||||
_Timer = new System.Timers.Timer();
|
||||
_Timer.Elapsed += ElapsedHandler;
|
||||
|
||||
// Set the Interval / start
|
||||
_Timer.Interval = IntervalMiliseconds;
|
||||
_Timer.Enabled = StartEnabled;
|
||||
if (StartEnabled)
|
||||
_Timer.Start();
|
||||
|
||||
// Keep the timer alive
|
||||
GC.KeepAlive(_Timer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer
|
||||
/// </summary>
|
||||
~TTimer()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
public void Start(uint IntervalMiliseconds)
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Interval = IntervalMiliseconds;
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="tsInterval">Interval as a TimeSpan</param>
|
||||
public void Start(TimeSpan tsInterval)
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Interval = tsInterval.TotalMilliseconds;
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Stop the Timer
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
_Timer.Enabled = false;
|
||||
_Timer.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the Timer Object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
// Use SupressFinalize in case a subclass
|
||||
// of this type implements a finalizer
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the Timer Object
|
||||
/// </summary>
|
||||
/// <param name="disposing">true, if called from within</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_Timer != null)
|
||||
_Timer.Dispose();
|
||||
}
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_Timer = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
162
Thread/TTimerDisp.cs
Normal file
162
Thread/TTimerDisp.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Timers;
|
||||
using System.Windows.Threading;
|
||||
using WinThread = System.Threading;
|
||||
|
||||
namespace Yaulw.Thread
|
||||
{
|
||||
/// <remarks>
|
||||
/// Wrapper class around Timer Object * Uses Dispatcher *
|
||||
/// </remarks>
|
||||
public class TTimerDisp : IDisposable
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
private Timer _Timer = new Timer();
|
||||
private bool _disposed = false;
|
||||
private Dispatcher _Dispatcher = null;
|
||||
private ElapsedEventHandler _DispatchedElapsedEvent = null;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Multi-threaded System.Timer that uses the Dispatcher to Fire the Event
|
||||
/// </summary>
|
||||
/// <param name="ElapsedHandler">Event Handler for Timer</param>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
/// <param name="StartEnabled">True to start the timer upon creation, false otherwise</param>
|
||||
/// <returns>A Timer Object, which should be Disposed by Caller</returns>
|
||||
public TTimerDisp(ElapsedEventHandler ElapsedHandler, int IntervalMiliseconds = 1000, bool StartEnabled = false)
|
||||
{
|
||||
if (ElapsedHandler != null)
|
||||
{
|
||||
_Timer = new System.Timers.Timer();
|
||||
|
||||
// The Primary Dispatcher thread is the thread that called us
|
||||
_Dispatcher = Dispatcher.CurrentDispatcher;
|
||||
_DispatchedElapsedEvent = ElapsedHandler;
|
||||
_Timer.Elapsed += new ElapsedEventHandler(_Timer_Elapsed);
|
||||
|
||||
// Set the Interval / start
|
||||
_Timer.Interval = IntervalMiliseconds;
|
||||
_Timer.Enabled = StartEnabled;
|
||||
if (StartEnabled)
|
||||
_Timer.Start();
|
||||
|
||||
// Keep the timer alive
|
||||
GC.KeepAlive(_Timer);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer
|
||||
/// </summary>
|
||||
~TTimerDisp()
|
||||
{
|
||||
Dispose(true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Helpers
|
||||
|
||||
/// <summary>
|
||||
/// For Dispatching the Event to the Primary Dispatcher Thread
|
||||
/// </summary>
|
||||
private void _Timer_Elapsed(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
object[] param_s = new object[] { sender, e };
|
||||
_Dispatcher.Invoke((ElapsedEventHandler)_DispatchedElapsedEvent, param_s);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="IntervalMiliseconds">Interval in Miliseconds</param>
|
||||
public void Start(uint IntervalMiliseconds)
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Interval = IntervalMiliseconds;
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Start the Timer at a new Interval
|
||||
/// </summary>
|
||||
/// <param name="tsInterval">Interval as a TimeSpan</param>
|
||||
public void Start(TimeSpan tsInterval)
|
||||
{
|
||||
Stop(); // First Stop(), an existing Timer
|
||||
_Timer.Interval = tsInterval.TotalMilliseconds;
|
||||
_Timer.Enabled = true;
|
||||
_Timer.Start();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manually Stop the Timer
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
_Timer.Enabled = false;
|
||||
_Timer.Stop();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IDisposable Members
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the Timer Object
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
// Use SupressFinalize in case a subclass
|
||||
// of this type implements a finalizer
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose the Timer Object
|
||||
/// </summary>
|
||||
/// <param name="disposing">true, if called from within</param>
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (_Timer != null)
|
||||
_Timer.Dispose();
|
||||
}
|
||||
|
||||
// Indicate that the instance has been disposed.
|
||||
_Timer = null;
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user