History

Renamed folders and separated GSF.Media and GSF.Net into separate projects.

StephenCWills committed 14 years ago

Commit ac1ef661 parent 45bce55628 files · +733 −461Browse files

Showing the changes to Source/Libraries/GSF.ServiceProcess/ServiceProcess.cs (1 of 628 files). Show all

Unified · Split

Source/Libraries/GSF.ServiceProcess/ServiceProcess.cs+400−0
@@ -0,0 +1,400 @@
1+//******************************************************************************************************
2+// ServiceProcess.cs - Gbtc
3+//
4+// Copyright � 2010, Grid Protection Alliance. All Rights Reserved.
5+//
6+// Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See
7+// the NOTICE file distributed with this work for additional information regarding copyright ownership.
8+// The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may
9+// not use this file except in compliance with the License. You may obtain a copy of the License at:
10+//
11+// http://www.opensource.org/licenses/eclipse-1.0.php
12+//
13+// Unless agreed to in writing, the subject software distributed under the License is distributed on an
14+// "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the
15+// License for the specific language governing permissions and limitations.
16+//
17+// Code Modification History:
18+// ----------------------------------------------------------------------------------------------------
19+// 09/13/2006 - Pinal C. Patel
20+// Generated original version of source code.
21+// 09/30/2008 - J. Ritchie Carroll
22+// Converted to C#.
23+// 03/03/2009 - Pinal C. Patel
24+// Edited code comments.
25+// 09/14/2009 - Stephen C. Wills
26+// Added new header and license agreement.
27+// 10/8/2012 - Danyelle Gilliam
28+// Modified Header
29+//
30+//******************************************************************************************************
31+
32+
33+
34+using GSF.Units;
35+using System;
36+using System.Text;
37+using System.Threading;
38+
39+namespace GSF.ServiceProcess
40+{
41+ #region [ Enumerations ]
42+
43+ /// <summary>
44+ /// Indicates the current state of <see cref="ServiceProcess"/>.
45+ /// </summary>
46+ public enum ServiceProcessState
47+ {
48+ /// <summary>
49+ /// <see cref="ServiceProcess"/> has not been started.
50+ /// </summary>
51+ Unprocessed,
52+ /// <summary>
53+ /// <see cref="ServiceProcess"/> is currently executing.
54+ /// </summary>
55+ Processing,
56+ /// <summary>
57+ /// <see cref="ServiceProcess"/> has completed processing.
58+ /// </summary>
59+ Processed,
60+ /// <summary>
61+ /// <see cref="ServiceProcess"/> was aborted.
62+ /// </summary>
63+ Aborted,
64+ /// <summary>
65+ /// <see cref="ServiceProcess"/> stopped due to exception.
66+ /// </summary>
67+ Exception
68+ }
69+
70+ #endregion
71+
72+ /// <summary>
73+ /// Represents a process that executes asynchronously inside a <see cref="ServiceHelper"/>.
74+ /// </summary>
75+ /// <seealso cref="ServiceHelper"/>
76+ public class ServiceProcess : IDisposable, IProvideStatus
77+ {
78+ #region [ Members ]
79+
80+ //Events
81+
82+ /// <summary>
83+ /// Occurs when the <see cref="CurrentState"/> of the <see cref="ServiceProcess"/> changes.
84+ /// </summary>
85+ public event EventHandler StateChanged;
86+
87+ // Fields
88+#if ThreadTracking
89+ private ManagedThread m_processThread;
90+#else
91+ private Thread m_processThread;
92+#endif
93+ private string m_name;
94+ private object[] m_arguments;
95+ private Action<string, object[]> m_executionMethod;
96+ private ServiceProcessState m_currentState;
97+ private DateTime m_executionStartTime;
98+ private DateTime m_executionStopTime;
99+ private bool m_disposed;
100+
101+ #endregion
102+
103+ #region [ Constructors ]
104+
105+ /// <summary>
106+ /// Initializes a new instance of the <see cref="ServiceProcess"/> class.
107+ /// </summary>
108+ /// <param name="executionMethod"><see cref="Delegate"/> that gets invoked when <see cref="Start()"/> is called.</param>
109+ /// <param name="name">Name of the <see cref="ServiceProcess"/>.</param>
110+ /// <param name="arguments">Arguments to be passed in to the <paramref name="executionMethod"/>.</param>
111+ public ServiceProcess(Action<string, object[]> executionMethod, string name, params object[] arguments)
112+ {
113+ m_name = name;
114+ m_arguments = arguments;
115+ m_executionMethod = executionMethod;
116+ m_currentState = ServiceProcessState.Unprocessed;
117+ }
118+
119+ /// <summary>
120+ /// Releases the unmanaged resources before the <see cref="ServiceProcess" /> object is reclaimed by <see cref="GC"/>.
121+ /// </summary>
122+ ~ServiceProcess()
123+ {
124+ Dispose(false);
125+ }
126+
127+ #endregion
128+
129+ #region [ Properties ]
130+
131+ /// <summary>
132+ /// Gets or sets the name of the <see cref="ServiceProcess"/>.
133+ /// </summary>
134+ /// <exception cref="ArgumentNullException">The value being assigned is a null or empty string.</exception>
135+ public string Name
136+ {
137+ get
138+ {
139+ return m_name;
140+ }
141+ set
142+ {
143+ if (string.IsNullOrEmpty(value))
144+ throw new ArgumentNullException("Name");
145+
146+ m_name = value;
147+ }
148+ }
149+
150+ /// <summary>
151+ /// Gets or sets the arguments to be passed in to the <see cref="ExecutionMethod"/>.
152+ /// </summary>
153+ public object[] Arguments
154+ {
155+ get
156+ {
157+ return m_arguments;
158+ }
159+ set
160+ {
161+ m_arguments = value;
162+ }
163+ }
164+
165+ /// <summary>
166+ /// Gets or sets the <see cref="Delegate"/> that gets invoked when <see cref="Start()"/> is called.
167+ /// </summary>
168+ /// <remarks>
169+ /// Argument1 gets the <see cref="Name"/> of the <see cref="ServiceProcess"/>.<br/>
170+ /// Argument2 gets the <see cref="Arguments"/> of the <see cref="ServiceProcess"/>.
171+ /// </remarks>
172+ public Action<string, object[]> ExecutionMethod
173+ {
174+ get
175+ {
176+ return m_executionMethod;
177+ }
178+ set
179+ {
180+ m_executionMethod = value;
181+ }
182+ }
183+
184+ /// <summary>
185+ /// Gets the current <see cref="ServiceProcessState"/>.
186+ /// </summary>
187+ public ServiceProcessState CurrentState
188+ {
189+ get
190+ {
191+ return m_currentState;
192+ }
193+ private set
194+ {
195+ m_currentState = value;
196+ OnStateChanged(); // Notify of the change in state.
197+ }
198+ }
199+
200+ /// <summary>
201+ /// Gets the <see cref="DateTime"/> when execution of <see cref="ServiceProcess"/> last started.
202+ /// </summary>
203+ public DateTime ExecutionStartTime
204+ {
205+ get
206+ {
207+ return m_executionStartTime;
208+ }
209+ }
210+
211+ /// <summary>
212+ /// Gets the <see cref="DateTime"/> when execution of <see cref="ServiceProcess"/> last completed.
213+ /// </summary>
214+ public DateTime ExecutionStopTime
215+ {
216+ get
217+ {
218+ return m_executionStopTime;
219+ }
220+ }
221+
222+ /// <summary>
223+ /// Gets the <see cref="Time"/> taken by the <see cref="ServiceProcess"/> during the last execution.
224+ /// </summary>
225+ public Time LastExecutionTime
226+ {
227+ get
228+ {
229+ return Ticks.ToSeconds(m_executionStopTime.Ticks - m_executionStartTime.Ticks);
230+ }
231+ }
232+
233+ /// <summary>
234+ /// Gets the descriptive status of the <see cref="ServiceProcess"/>.
235+ /// </summary>
236+ public string Status
237+ {
238+ get
239+ {
240+ StringBuilder status = new StringBuilder();
241+
242+ status.Append(" Process Name: ");
243+ status.Append(m_name);
244+ status.AppendLine();
245+ status.Append(" Current State: ");
246+ status.Append(m_currentState.ToString());
247+ status.AppendLine();
248+ status.Append(" Execution Start Time: ");
249+
250+ if (m_executionStartTime != DateTime.MinValue)
251+ {
252+ status.Append(m_executionStartTime.ToString());
253+ }
254+ else
255+ {
256+ status.Append("N/A");
257+ }
258+
259+ status.AppendLine();
260+ status.Append(" Execution Stop Time: ");
261+
262+ if (m_executionStopTime != DateTime.MinValue)
263+ {
264+ status.Append(m_executionStopTime.ToString());
265+ }
266+ else
267+ {
268+ status.Append("N/A");
269+ }
270+
271+ status.AppendLine();
272+ status.Append(" Last Execution Time: ");
273+ status.Append(LastExecutionTime.ToString());
274+ status.AppendLine();
275+
276+ return status.ToString();
277+ }
278+ }
279+
280+ #endregion
281+
282+ #region [ Methods ]
283+
284+ /// <summary>
285+ /// Starts the execution of <see cref="ServiceProcess"/>.
286+ /// </summary>
287+ public void Start()
288+ {
289+ Start(m_arguments);
290+ }
291+
292+ /// <summary>
293+ /// Starts the execution of <see cref="ServiceProcess"/>.
294+ /// </summary>
295+ /// <param name="arguments">Arguments to be passed in to the <see cref="ExecutionMethod"/>.</param>
296+ public void Start(object[] arguments)
297+ {
298+ // Start the execution on a seperate thread.
299+#if ThreadTracking
300+ m_processThread = new ManagedThread(InvokeExecutionMethod);
301+ m_processThread.Name = "TVA.ServiceProcess.ServiceProcess.InvokeExecutionMethod() [" + m_name + "]";
302+#else
303+ m_processThread = new Thread(InvokeExecutionMethod);
304+#endif
305+ m_processThread.Start(arguments);
306+ }
307+
308+ /// <summary>
309+ /// Stops the execution of <see cref="ServiceProcess"/> if it executing.
310+ /// </summary>
311+ public void Abort()
312+ {
313+ // We'll abort the process only if it is currently executing.
314+ if (m_processThread != null)
315+ {
316+ if (m_processThread.IsAlive)
317+ m_processThread.Abort();
318+ }
319+ m_processThread = null;
320+ }
321+
322+ /// <summary>
323+ /// Releases all the resources used by the <see cref="ServiceProcess"/> object.
324+ /// </summary>
325+ public void Dispose()
326+ {
327+ Dispose(true);
328+ GC.SuppressFinalize(this);
329+ }
330+
331+ /// <summary>
332+ /// Releases the unmanaged resources used by the <see cref="ServiceProcess"/> and optionally releases the managed resources.
333+ /// </summary>
334+ /// <param name="disposing">true to release both managed and unmanaged resources; false to release only unmanaged resources.</param>
335+ protected virtual void Dispose(bool disposing)
336+ {
337+ if (!m_disposed)
338+ {
339+ try
340+ {
341+ // This will be done regardless of whether the object is finalized or disposed.
342+ Abort();
343+ if (disposing)
344+ {
345+ // This will be done only when the object is disposed by calling Dispose().
346+ m_executionMethod = null;
347+ }
348+ }
349+ finally
350+ {
351+ m_disposed = true; // Prevent duplicate dispose.
352+ }
353+ }
354+ }
355+
356+ /// <summary>
357+ /// Raises the <see cref="StateChanged"/> event.
358+ /// </summary>
359+ protected virtual void OnStateChanged()
360+ {
361+ if (StateChanged != null)
362+ StateChanged(this, EventArgs.Empty);
363+ }
364+
365+ private void InvokeExecutionMethod(object state)
366+ {
367+ if (m_executionMethod != null)
368+ {
369+ CurrentState = ServiceProcessState.Processing;
370+ m_executionStartTime = DateTime.Now;
371+ m_executionStopTime = DateTime.MinValue;
372+
373+ try
374+ {
375+ // We'll keep the invocation of the delegate in Try...Catch to absorb any exceptions that
376+ // were not handled by the consumer.
377+ m_executionMethod(m_name, state as object[]);
378+
379+ CurrentState = ServiceProcessState.Processed;
380+ }
381+ catch (ThreadAbortException)
382+ {
383+ CurrentState = ServiceProcessState.Aborted;
384+ }
385+ catch (Exception)
386+ {
387+ // We'll absorb any exceptions if unhandled by the client.
388+ CurrentState = ServiceProcessState.Exception;
389+ }
390+ finally
391+ {
392+ m_executionStopTime = DateTime.Now;
393+ }
394+ }
395+ m_processThread = null;
396+ }
397+
398+ #endregion
399+ }
400+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t