Commit f5ed784

mo khan <mo@mokhan.ca>
2010-07-19 18:55:31
figured out why the application was not getting shutdown. needed to stop the command processor and the queue.
1 parent f775664
product/client/client.ui/bootstrappers/Bootstrapper.cs
@@ -71,13 +71,14 @@ namespace presentation.windows.bootstrappers
             builder.Register<WPFCommandBuilder>().As<UICommandBuilder>();
 
             // queries
-
             builder.Register<PublishEventHandler<AddedNewFamilyMember>>().As<Handler>();
 
             Resolve.the<IEnumerable<NeedStartup>>().each(x => x.run());
             Resolve.the<CommandProcessor>().run();
 
+            shell_window.Closed += (o, e) => Resolve.the<ServiceBus>().publish<ApplicationShuttingDown>();
             shell_window.Closed += (o, e) => Resolve.the<CommandProcessor>().stop();
+            shell_window.Closed += (o, e) => manager.Dispose();
             return shell_window;
         }
     }
product/client/client.ui/client.csproj
@@ -212,6 +212,7 @@
     <Compile Include="views\StatusBarRegion.xaml.cs">
       <DependentUpon>StatusBarRegion.xaml</DependentUpon>
     </Compile>
+    <Compile Include="WPFApplication.cs" />
     <Compile Include="WpfApplicationController.cs" />
     <Compile Include="WpfPresenterFactory.cs" />
     <EmbeddedResource Include="Properties\Resources.resx">
product/client/client.ui/Program.cs
@@ -4,6 +4,7 @@ using System.IO;
 using System.Security.Principal;
 using System.Windows;
 using System.Windows.Threading;
+using Gorilla.Commons.Infrastructure.Logging;
 using presentation.windows.bootstrappers;
 using presentation.windows.views;
 
@@ -14,23 +15,33 @@ namespace presentation.windows
         [STAThread]
         static public void Main(string[] args)
         {
-            Process.Start(get_startup_path_using(args));
+            Process.Start(new ProcessStartInfo
+            {
+                FileName = get_service_startup_path(args),
+                //WindowStyle = ProcessWindowStyle.Hidden,
+            });
+            AppDomain.CurrentDomain.UnhandledException += (o, e) =>
+            {
+                (e.ExceptionObject as Exception).add_to_log();
+            };
             AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
             Dispatcher.CurrentDispatcher.UnhandledException += (o, e) =>
             {
+                e.Exception.add_to_log();
                 new ErrorWindow {DataContext = e.Exception}.ShowDialog();
+                e.Handled = true;
             };
-            new Application
+            new WPFApplication
             {
-                ShutdownMode = ShutdownMode.OnMainWindowClose
+                ShutdownMode = ShutdownMode.OnMainWindowClose,
             }.Run(Bootstrapper.create_window());
         }
 
-        static string get_startup_path_using(string[] args)
+        static string get_service_startup_path(string[] args)
         {
             if (args.Length > 0)
-                return Path.Combine(args[0], @"presentation.windows.server.exe");
-            return Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\server\bin\Debug\presentation.windows.server.exe"));
+                return Path.Combine(args[0], @"momoney.server.exe");
+            return Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\server\bin\Debug\momoney.server.exe"));
         }
     }
 }
\ No newline at end of file
product/client/client.ui/WPFApplication.cs
@@ -0,0 +1,6 @@
+using System.Windows;
+
+namespace presentation.windows
+{
+    public class WPFApplication : Application {}
+}
\ No newline at end of file
product/client/common/messages/ApplicationShuttingDown.cs
@@ -0,0 +1,9 @@
+using System;
+using ProtoBuf;
+
+namespace presentation.windows.common.messages
+{
+    [Serializable]
+    [ProtoContract]
+    public class ApplicationShuttingDown : IEvent {}
+}
\ No newline at end of file
product/client/common/common.csproj
@@ -87,6 +87,7 @@
     <Compile Include="IEvent.cs" />
     <Compile Include="MessageHandler.cs" />
     <Compile Include="messages\AddedNewFamilyMember.cs" />
+    <Compile Include="messages\ApplicationShuttingDown.cs" />
     <Compile Include="messages\CreateNewDetailAccount.cs" />
     <Compile Include="messages\FamilyMemberToAdd.cs" />
     <Compile Include="messages\FindAllFamily.cs" />
product/client/server/handlers/ShutdownApplicationCommand.cs
@@ -0,0 +1,16 @@
+using System;
+using Gorilla.Commons.Infrastructure.Logging;
+using presentation.windows.common;
+using presentation.windows.common.messages;
+
+namespace presentation.windows.server.handlers
+{
+    public class ShutdownApplicationCommand : AbstractHandler<ApplicationShuttingDown>
+    {
+        public override void handle(ApplicationShuttingDown item)
+        {
+            this.log().debug("shutting down");
+            Environment.Exit(Environment.ExitCode);
+        }
+    }
+}
\ No newline at end of file
product/client/server/Bootstrapper.cs
@@ -55,6 +55,7 @@ namespace presentation.windows.server
             builder.Register<AddNewFamilyMemberHandler>().As<Handler>();
             builder.Register<FindAllFamilyHandler>().As<Handler>();
             builder.Register<SaveNewAccountCommand>().As<Handler>();
+            builder.Register<ShutdownApplicationCommand>().As<Handler>();
 
             // queries
 
product/client/server/server.csproj
@@ -9,7 +9,7 @@
     <OutputType>Exe</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>presentation.windows.server</RootNamespace>
-    <AssemblyName>presentation.windows.server</AssemblyName>
+    <AssemblyName>momoney.server</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <FileUpgradeFlags>
@@ -128,6 +128,7 @@
     <Compile Include="domain\Person.cs" />
     <Compile Include="handlers\FindAllFamilyHandler.cs" />
     <Compile Include="handlers\SaveNewAccountCommand.cs" />
+    <Compile Include="handlers\ShutdownApplicationCommand.cs" />
     <Compile Include="NHibernateBootstrapper.cs" />
     <Compile Include="orm\AccountRepository.cs" />
     <Compile Include="orm\EmptyUnitOfWork.cs" />
product/commons/infrastructure/threading/AsynchronousCommandProcessor.cs
@@ -4,110 +4,110 @@ using System.Threading;
 using Gorilla.Commons.Infrastructure.Logging;
 using gorilla.commons.utility;
 
-namespace gorilla.commons.infrastructure.threading
-{
-    public class AsynchronousCommandProcessor : CommandProcessor
-    {
-        readonly Queue<Command> queued_commands;
-        readonly EventWaitHandle manual_reset;
-        readonly IList<Thread> worker_threads;
-        bool keep_working;
-
-        static public readonly Command Empty = new EmptyCommand();
-
-        public AsynchronousCommandProcessor()
-        {
-            queued_commands = new Queue<Command>();
-            worker_threads = new List<Thread>();
-            manual_reset = new ManualResetEvent(false);
-        }
-
-        public void add(Action command)
-        {
-            add(new AnonymousCommand(command));
-        }
-
-        public void add(Command command_to_process)
-        {
-            lock (queued_commands)
-            {
-                if (queued_commands.Contains(command_to_process)) return;
-                queued_commands.Enqueue(command_to_process);
-                reset_thread();
-            }
-        }
-
-        public void run()
-        {
-            reset_thread();
-            keep_working = true;
-            var worker_thread = new Thread(run_commands);
-            worker_thread.SetApartmentState(ApartmentState.STA);
-            worker_threads.Add(worker_thread);
-            worker_thread.Start();
-        }
-
-        public void stop()
-        {
-            keep_working = false;
-            manual_reset.Set();
-            //manual_reset.Close();
-        }
-
-        [STAThread]
-        void run_commands()
-        {
-            while (keep_working)
-            {
-                manual_reset.WaitOne();
-                run_next_command();
-            }
-        }
-
-        void run_next_command()
-        {
-            var command = Empty;
-            within_lock(() =>
-                        {
-                            if (queued_commands.Count == 0)
-                                manual_reset.Reset();
-                            else
-                                command = queued_commands.Dequeue();
-                        });
-            safely_invoke(() =>
-                          {
-                              command.run();
-                          });
-            reset_thread();
-        }
-
-        void safely_invoke(Action action)
-        {
-            try
-            {
-                action();
-            }
-            catch (Exception e)
-            {
-                this.log().error(e);
-            }
-        }
-
-        void reset_thread()
-        {
-            within_lock(() =>
-                        {
-                            if (queued_commands.Count > 0) manual_reset.Set();
-                            else manual_reset.Reset();
-                        });
-        }
-
-        void within_lock(Action action)
-        {
-            lock (queued_commands)
-            {
-                action();
-            }
-        }
-    }
+namespace gorilla.commons.infrastructure.threading
+{
+    public class AsynchronousCommandProcessor : CommandProcessor
+    {
+        readonly Queue<Command> queued_commands;
+        readonly EventWaitHandle manual_reset;
+        readonly IList<Thread> worker_threads;
+        bool keep_working;
+
+        static public readonly Command Empty = new EmptyCommand();
+
+        public AsynchronousCommandProcessor()
+        {
+            queued_commands = new Queue<Command>();
+            worker_threads = new List<Thread>();
+            manual_reset = new ManualResetEvent(false);
+        }
+
+        public void add(Action command)
+        {
+            add(new AnonymousCommand(command));
+        }
+
+        public void add(Command command_to_process)
+        {
+            lock (queued_commands)
+            {
+                if (queued_commands.Contains(command_to_process)) return;
+                queued_commands.Enqueue(command_to_process);
+                reset_thread();
+            }
+        }
+
+        public void run()
+        {
+            reset_thread();
+            keep_working = true;
+            var worker_thread = new Thread(run_commands);
+            worker_thread.SetApartmentState(ApartmentState.STA);
+            worker_threads.Add(worker_thread);
+            worker_thread.Start();
+        }
+
+        public void stop()
+        {
+            keep_working = false;
+            manual_reset.Set();
+            //manual_reset.Close();
+        }
+
+        [STAThread]
+        void run_commands()
+        {
+            while (keep_working)
+            {
+                manual_reset.WaitOne();
+                run_next_command();
+            }
+        }
+
+        void run_next_command()
+        {
+            var command = Empty;
+            within_lock(() =>
+                        {
+                            if (queued_commands.Count == 0)
+                                manual_reset.Reset();
+                            else
+                                command = queued_commands.Dequeue();
+                        });
+            safely_invoke(() =>
+                          {
+                              command.run();
+                          });
+            reset_thread();
+        }
+
+        void safely_invoke(Action action)
+        {
+            try
+            {
+                action();
+            }
+            catch (Exception e)
+            {
+                this.log().error(e);
+            }
+        }
+
+        void reset_thread()
+        {
+            within_lock(() =>
+                        {
+                            if (queued_commands.Count > 0) manual_reset.Set();
+                            else manual_reset.Reset();
+                        });
+        }
+
+        void within_lock(Action action)
+        {
+            lock (queued_commands)
+            {
+                action();
+            }
+        }
+    }
 }
\ No newline at end of file