diff --git a/OATCommunications/Log.cs b/OATCommunications/Log.cs index 6f8cbcd..99e2638 100644 --- a/OATCommunications/Log.cs +++ b/OATCommunications/Log.cs @@ -19,6 +19,8 @@ public class Log private static List lstBuffer = new List(); private static DateTime dtLastUpdate = DateTime.Now.AddSeconds(5.0); private static int maxBuffered = 0; + private static bool logging = true; + public static string Filename { @@ -82,34 +84,43 @@ private static string FormatMessage(string message, object[] args) return sb.ToString(); } + protected static void Flush() + { + lock (Log.oLock) + { + var lines = string.Join("\r\n", Log.lstBuffer.ToArray()) + "\r\n"; + File.AppendAllText(Log.sPath, lines); + Log.lstBuffer.Clear(); + } + } + public static void WriteLine(string message, params object[] args) { - if ((DateTime.UtcNow - Log.dtLastUpdate).TotalMilliseconds > 1000.0) + if (logging) { - lock (Log.oLock) + if ((DateTime.UtcNow - Log.dtLastUpdate).TotalMilliseconds > 1000.0) { - var lines = string.Join("\r\n", Log.lstBuffer.ToArray()) + "\r\n"; - File.AppendAllText(Log.sPath, lines); - Log.lstBuffer.Clear(); + Log.Flush(); + Log.dtLastUpdate = DateTime.UtcNow; } - Log.dtLastUpdate = DateTime.UtcNow; - } - string sLine = FormatMessage(message, args); + string sLine = FormatMessage(message, args); - lock (Log.oLock) - { - Log.lstBuffer.Add(sLine); - Debug.WriteLine(sLine); - if (Log.lstBuffer.Count > Log.maxBuffered) + lock (Log.oLock) { - Log.maxBuffered = Log.lstBuffer.Count; + Log.lstBuffer.Add(sLine); + Debug.WriteLine(sLine); + if (Log.lstBuffer.Count > Log.maxBuffered) + { + Log.maxBuffered = Log.lstBuffer.Count; + } } } } public static void Quit() { + logging = false; if (Log.lstBuffer.Any()) { lock (Log.oLock) diff --git a/OATControl/App.xaml.cs b/OATControl/App.xaml.cs index 39cc915..36aa65e 100644 --- a/OATControl/App.xaml.cs +++ b/OATControl/App.xaml.cs @@ -7,6 +7,9 @@ using System.Threading.Tasks; using System.Windows; using OATCommunications.Utilities; +using System.Threading; +using System.Windows.Threading; + namespace OATControl { /// @@ -15,6 +18,17 @@ namespace OATControl public partial class App : Application { + public App() + { + Log.Init("OatControl"); + + // Add the event handler for handling non-UI thread exceptions to the event. + AppDomain.CurrentDomain.UnhandledException += App.UnhandledException; + + this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App.AppDispatcherUnhandledException); + + + } protected override void OnStartup(StartupEventArgs e) { ThemeManager.AddAccent("RedAccent", new Uri("pack://application:,,,/OATControl;component/Resources/RedAccent.xaml")); @@ -30,7 +44,7 @@ protected override void OnStartup(StartupEventArgs e) ThemeManager.GetAccent("RedAccent"), ThemeManager.GetAppTheme("RedTheme")); - Log.Init("OatControl"); + base.OnStartup(e); } @@ -40,5 +54,44 @@ protected override void OnExit(ExitEventArgs e) base.OnExit(e); } - } + + private static int exceptionReentrancy = 0; + + /// + /// Delegate's instance to react to unhandled exception event happened on not UI thread. + /// + /// the object where event happened. + /// The exception related information. + private static void UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + if (Interlocked.CompareExchange(ref App.exceptionReentrancy, 1, 0) == 0) + { + Log.WriteLine("EXCPTN: Entered UnhandledException handler.\nException:\n{0}", (e.ExceptionObject != null) ? e.ExceptionObject.ToString() : "No exception!"); + } + + Log.Quit(); + Environment.Exit(-1); + } + + + //------------------------------------------------------------------------------------------------------------- + /// + /// The application's unhandled exception handler. + /// + /// The sender. + /// The instance containing the event data. + static void AppDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) + { + if (Interlocked.CompareExchange(ref App.exceptionReentrancy, 1, 0) == 0) + { + Log.WriteLine("EXCPTN: Entered AppDispatcherUnhandledException handler.\nException:\n{0}\nStacktrace:\n{1}", (e.Exception != null) ? e.Exception.ToString() : "No Exception!", (e.Exception != null) ? e.Exception.StackTrace : "No Stacktrace!"); + + // Prevent default unhandled exception processing + e.Handled = true; + } + + Log.Quit(); + } + + } } diff --git a/OATControl/MainWindow.xaml b/OATControl/MainWindow.xaml index ad44590..936c811 100644 --- a/OATControl/MainWindow.xaml +++ b/OATControl/MainWindow.xaml @@ -8,7 +8,7 @@ xmlns:controls="clr-namespace:OATControl.Controls" xmlns:converters="clr-namespace:OATControl.Converters" mc:Ignorable="d" - Title="{Binding Version, StringFormat={} OpenAstroTracker Control V{0}}" MinHeight="698" MinWidth="720" Height="700" Width="720"> + Title="{Binding Version, StringFormat={} OpenAstroTracker Control V{0}}" MinHeight="705" MinWidth="720" Height="705" Width="720"> @@ -302,7 +302,8 @@ - + + @@ -315,7 +316,7 @@ - + @@ -357,7 +358,8 @@ - + - + - + @@ -441,8 +443,8 @@ + - @@ -457,7 +459,7 @@ - + @@ -525,11 +527,10 @@ - - + + - - + @@ -539,11 +540,12 @@ -