| @@ -23,6 +23,7 @@ · 22 unmodified lines |
| 23 | 23 | |
| 24 | 24 | using System; |
| 25 | 25 | using System.Collections.Generic; |
| 26 | +using System.ComponentModel; |
| 26 | 27 | using GSF.Collections; |
| 27 | 28 | using GSF.Diagnostics; |
| 28 | 29 | |
| @@ -60,15 +61,16 @@ namespace GSF.Threading · 31 unmodified lines |
| 60 | 61 | /// Gets if this process is shutting down. |
| 61 | 62 | /// </summary> |
| 62 | 63 | public static bool IsShuttingDown { get; private set; } |
| 64 | + |
| 63 | 65 | /// <summary> |
| 64 | 66 | /// Gets if this process has already shut down. |
| 65 | 67 | /// </summary> |
| 66 | 68 | public static bool HasShutdown { get; private set; } |
| 67 | 69 | |
| 68 | | − private static List<WeakAction> s_onShutdownCallbackFirst; |
| 69 | | − private static List<WeakAction> s_onShutdownCallbackDefault; |
| 70 | | − private static List<WeakAction> s_onShutdownCallbackLast; |
| 71 | | − private static object s_syncRoot; |
| 70 | + private static readonly List<WeakAction> s_onShutdownCallbackFirst; |
| 71 | + private static readonly List<WeakAction> s_onShutdownCallbackDefault; |
| 72 | + private static readonly List<WeakAction> s_onShutdownCallbackLast; |
| 73 | + private static readonly object s_syncRoot; |
| 72 | 74 | |
| 73 | 75 | static ShutdownHandler() |
| 74 | 76 | { |
| @@ -128,6 +130,7 @@ namespace GSF.Threading · 53 unmodified lines |
| 128 | 130 | |
| 129 | 131 | list.RemoveWhere(x => !x.IsAlive); |
| 130 | 132 | list.Add(new WeakAction(callback)); |
| 133 | + |
| 131 | 134 | return true; |
| 132 | 135 | } |
| 133 | 136 | } |
| @@ -135,19 +138,19 @@ namespace GSF.Threading · 1 unmodified line |
| 135 | 138 | private static void InitiateSafeShutdown(object sender, EventArgs e) |
| 136 | 139 | { |
| 137 | 140 | List<WeakAction> shutdownList = new List<WeakAction>(); |
| 141 | + |
| 138 | 142 | lock (s_syncRoot) |
| 139 | 143 | { |
| 140 | 144 | if (IsShuttingDown) |
| 141 | | − { |
| 142 | 145 | return; |
| 143 | | − } |
| 146 | + |
| 144 | 147 | IsShuttingDown = true; |
| 145 | 148 | shutdownList.AddRange(s_onShutdownCallbackFirst); |
| 146 | 149 | shutdownList.AddRange(s_onShutdownCallbackDefault); |
| 147 | 150 | shutdownList.AddRange(s_onShutdownCallbackLast); |
| 148 | 151 | } |
| 149 | 152 | |
| 150 | | − foreach (var weakAction in shutdownList) |
| 153 | + foreach (WeakAction weakAction in shutdownList) |
| 151 | 154 | { |
| 152 | 155 | try |
| 153 | 156 | { |
| @@ -160,22 +163,22 @@ namespace GSF.Threading · 6 unmodified lines |
| 160 | 163 | } |
| 161 | 164 | |
| 162 | 165 | Logger.Shutdown(); |
| 166 | + |
| 163 | 167 | HasShutdown = true; |
| 164 | 168 | } |
| 165 | 169 | |
| 166 | 170 | /// <summary> |
| 167 | | − /// Requests that certain components initiate a safe shutdown. This method |
| 168 | | − /// should only be called when the main thread exits. Calling this outside |
| 169 | | − /// of the application exiting could result in unpredictable behavior. |
| 171 | + /// Requests that certain components initiate a safe shutdown. |
| 170 | 172 | /// </summary> |
| 171 | | − /// <param name="areYouSure">To ensure proper use, specify this value as a constant. 'OnlyCallThisWhenMainExits'</param> |
| 172 | | − public static void InitiateSafeShutdown(string areYouSure) |
| 173 | + /// <remarks> |
| 174 | + /// This method should only be called when the main thread exits. Calling this outside |
| 175 | + /// of the application exiting could result in unpredictable behavior. |
| 176 | + /// </remarks> |
| 177 | +#if !SQLCLR |
| 178 | + [EditorBrowsable(EditorBrowsableState.Advanced)] |
| 179 | +#endif |
| 180 | + public static void InitiateSafeShutdown() |
| 173 | 181 | { |
| 174 | | − if (areYouSure != "OnlyCallThisWhenMainExits") |
| 175 | | − { |
| 176 | | − throw new InvalidOperationException("This method must only be called when the main thread exits."); |
| 177 | | − } |
| 178 | | − |
| 179 | 182 | InitiateSafeShutdown(null, null); |
| 180 | 183 | } |
| 181 | 184 | } |