// public method to add a new worker into the collection private void AddProcess(WorkerFormatter workerDefinition) { if (workerReferences != null) { // validate the name is unique string processName = workerDefinition.ProcessName; if (workerReferences.ContainsKey(processName)) { throw new ArgumentException("Process Name Must be Unique: " + processName); } // create a worker object in the worker array workerReferences.Add(processName, new WorkerInstance(workerDefinition)); } }
// the work object constructor that validates and saves the constructor defintion public WorkerInstance(WorkerFormatter workerFormatter) { // save the constructor definition and indicate process starting workerDefinition = workerFormatter; workerDefinition.ProcessStatus = WorkerFormatter.SFProcessStatus.StatusInitialized; // indicate the worker class has not been started or paused workerRunning = false; workerPaused = false; // validate the number of threads is within an acceptable range if (workerDefinition.NumberThreads <= 0 || workerDefinition.NumberThreads > 255) { throw new ArgumentException("Must have a postive value for the number of threads"); } // validate the worker object has been correctly assigned a name if (workerDefinition.ProcessName == null) { throw new ArgumentException("Must have a non-null value for the process name"); } // ensure that the description has a value if (workerDefinition.ProcessDesc == null) { workerDefinition.ProcessDesc = workerDefinition.ProcessName; } // validate the input and error queue path has been passed if (workerDefinition.InputQueue == null || workerDefinition.ErrorQueue == null) { throw new ArgumentException("Must have a non-null value for the queues"); } // save a reference to the parent service and worker description serviceDesc = MSMQListner.ServiceControlDesc; workerDesc = workerDefinition.ProcessDesc; }
protected override void OnStart(string[] args) { LogInformation("Service to Start"); // register the perfmon counters PerfmonInstall(); XmlDocument configXmlDoc; WorkerFormatter workerDefinition; // access the XML configuration file and validate against the schema try { configXmlDoc = new XmlDocument(); //Load the the document with the last book node. configXmlDoc.Load(ConfigurationSettings.AppSettings["ConfigurationFile"].ToString()); } catch (Exception ex) { PerfmonUninstall(); LogError("Invalid XML Configuration File: " + ex.Message); throw ex; } try { //LogInformation("File loaded and ready to add"); foreach (XmlNode processXmlDefinition in configXmlDoc.GetElementsByTagName("ThreadDefinition")) { workerDefinition = new WorkerFormatter(); string processName = processXmlDefinition.Attributes.GetNamedItem("ThreadName").Value; workerDefinition.ProcessName = processName; workerDefinition.NumberThreads = Convert.ToInt32(processXmlDefinition.Attributes.GetNamedItem("NumberThreads").Value); // determine the transaction status of the processing switch (Convert.ToBoolean(processXmlDefinition.Attributes.GetNamedItem("Transactions").Value)) { case false: workerDefinition.Transactions = WorkerFormatter.SFTransactions.NotRequired; break; case true: workerDefinition.Transactions = WorkerFormatter.SFTransactions.Required; break; default: throw new ApplicationException("Unknown Required Transaction State"); } workerDefinition.ProcessDesc = processXmlDefinition.ChildNodes[0].InnerText; workerDefinition.InputQueue = processXmlDefinition.ChildNodes[1].InnerText; workerDefinition.ErrorQueue = processXmlDefinition.ChildNodes[2].InnerText; workerDefinition.SmtpServer = processXmlDefinition.ChildNodes[3].InnerText; workerDefinition.ErrorEmails = processXmlDefinition.ChildNodes[4].InnerText; workerDefinition.Subject = processXmlDefinition.ChildNodes[5].InnerText; workerDefinition.MessageLimit = int.Parse(processXmlDefinition.ChildNodes[6].InnerText); workerDefinition.Delay = int.Parse(processXmlDefinition.ChildNodes[7].InnerText); AddProcess(workerDefinition); // LogInformation("adding: " + processName + " Threads: " + workerDefinition.NumberThreads); } } catch (Exception ex) { PerfmonUninstall(); LogError("Service Start Failed: " + ex.Message); workerReferences.Clear(); throw ex; } // call the start method on each worker object foreach (WorkerInstance workerReference in workerReferences.Values) { try { workerReference.StartService(); } catch (Exception) { // a start failed but continue with other creations // one could decide to abort the start process at this point } } // indicate the service has started LogInformation("Service Started"); }