using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Reflection;
// Ooganizer Namespaces
using Foo.Platform;
using System.Windows.Threading;
namespace Foo.ClientServices.ButtonWPForm
{
///
/// This class is responsible for creation and deltion of ButtonFormMgr.cs on a
/// Dispatcher Thread. ~The Dispatcher is responsible for all the messages being passed
/// for the Form Objects, it must be running at all times and created before any forms get
/// created.
///
[ComVisible(false)]
class DispatcherThread
{
// Member Variables
private static Thread s_DispatcherThread = null;
private static bool s_DispatcherThreadIsInitialized = false;
internal static ButtonFormMgr s_ButtonFormMgr = null;
// Declare the Log4net Variable
private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType);
///
/// Constructor by default will launch the thread if needed
///
static DispatcherThread()
{
Log.Info(string.Format("{0}() - DispatcherThread() called", MethodBase.GetCurrentMethod().Name));
StartDispatcherThreadIfNeeded();
}
///
/// Use this property to set the Dispatcher to running / not running
///
public static bool Run
{
get { return s_DispatcherThreadIsInitialized; }
set
{
if (!value)
TerminateDispatcherThreadIfNeeded();
s_DispatcherThreadIsInitialized = value;
}
}
///
/// Message Loop Thread for ButtonForm
///
private static void DispatcherThreadProc()
{
// Create ButtonFormMgr Object on this thread *Allow global access to the object*
Log.Info(string.Format("{0}() - About to new ButtonFormMgr via DispatcherThread", MethodBase.GetCurrentMethod().Name));
s_ButtonFormMgr = new ButtonFormMgr(Dispatcher.CurrentDispatcher);
Log.Info(string.Format("{0}() - ButtonWPForm DispatcherThread is initialized s_DispatcherThreadIsInitialized is True", MethodBase.GetCurrentMethod().Name));
s_DispatcherThreadIsInitialized = true; // always set to true to allow caller to exit out
if (s_ButtonFormMgr != null)
{
Log.Info(string.Format("{0}() - ButtonFormMgr Launched via DispatcherThread", MethodBase.GetCurrentMethod().Name));
//Enter Dispatcher Message Loop
System.Windows.Threading.Dispatcher.Run();
}
else
{
Log.Error(string.Format("{0}() - ButtonFormMgr Launch Failed! Exiting Thread - Major Error must have occured", MethodBase.GetCurrentMethod().Name));
// exit thread - no need to stay here
}
}
///
/// Use this function to start ThreadProc(above) if needed. COM+ can shutdown the thread anytime,
/// we need to make sure that the thread is alive BEFORE calling ButtonForms
///
private static void StartDispatcherThreadIfNeeded()
{
if (s_DispatcherThread != null && s_DispatcherThread.IsAlive)
{
return;
}
else
{
s_DispatcherThreadIsInitialized = false;
// Start a new Thread so it can become the Message Loop
s_DispatcherThread = new Thread(new ThreadStart(DispatcherThread.DispatcherThreadProc));
// GUI components require the thread to be STA; otherwise throws an error
s_DispatcherThread.SetApartmentState(ApartmentState.STA);
Log.Info(string.Format("{0}() - Starting DispatcherThread...", MethodBase.GetCurrentMethod().Name));
s_DispatcherThread.Start();
Log.Info(string.Format("{0}() - DispatcherThread Started.", MethodBase.GetCurrentMethod().Name));
// Make sure the Application Object is running
// (COM will eventually just time out otherwise)
//while (!s_DispatcherThreadIsInitialized)
// System.Threading.Thread.Sleep(20); // Syncronous call
}
}
///
/// Terminates all ButtonForm Objects and the Message Dispatcher Thread *do this only on shutdown*
///
private static void TerminateDispatcherThreadIfNeeded()
{
if (s_DispatcherThreadIsInitialized)
{
// Delete ButtonFormMgr and all ButtonForms from this thread
s_ButtonFormMgr.TerminateDISP();
s_ButtonFormMgr = null;
s_DispatcherThread.Abort();
s_DispatcherThreadIsInitialized = false;
Log.Info(string.Format("{0}() - ButtonWPForm is DispatcherThread shutdown s_DispatcherThreadIsInitialized is False", MethodBase.GetCurrentMethod().Name));
}
}
}
}