【发布时间】:2013-08-19 08:45:31
【问题描述】:
有 5 个 Windows 服务使用相同的 exe。这些在 SCM 中设置为自动。当服务器重新启动时,这些 Windows 服务会抛出错误“Windows 服务无法及时启动”。问题在于代码的编写方式。为了确定问题出在哪里,我在代码中编写了 EventView 日志记录,但看到每次 SCM 尝试启动服务时都会调用主入口点,即静态 void main。下面是代码
静态类程序 { /// /// 应用程序的主入口点。 /// /// 带有事件记录的原始代码 静态无效主要() { GetAllServicesToRun(); }
private static void GetAllServicesToRun()
{
EventLog ev = new EventLog("");
try
{
string msg = string.Empty;
ev.Source = "STARTAPPLN";
msg = "Appln start" + " at time: " + DateTime.Now.ToString("hh:mm:ss:fff");
ev.WriteEntry(msg, EventLogEntryType.FailureAudit);
TaskServiceConfig tsc = (TaskServiceConfig)System.Configuration.ConfigurationManager.GetSection("TaskServiceConfigSection");
IList<ServiceBase> ServicesToRun = new List<ServiceBase>();
int i = 0;
foreach (var config in tsc.TaskServices)
{
Hashtable arguments = new Hashtable();
arguments.Add("taskServiceName", ((TaskServices.ConfigSection.TaskServiceConfig.TaskServiceElement)config).Value);
ev.Source = "ForLoop_" + i.ToString() + "_START";
msg = "start For Loop_" + i.ToString() + " at time: " + DateTime.Now.ToString("hh:mm:ss:fff") + " :SN: " + arguments["taskServiceName"].ToString();
ev.WriteEntry(msg, EventLogEntryType.FailureAudit);
ServicesToRun.Add(new Service1(arguments));
ev.Source = "ForLoop_" + i.ToString() + "_END";
msg = "end For Loop_" + i.ToString() + " at time: " + DateTime.Now.ToString("hh:mm:ss:fff");
ev.WriteEntry(msg, EventLogEntryType.FailureAudit);
i = i + 1;
}
ServiceBase.Run(ServicesToRun.ToArray());
}
由于主入口点被多次调用,SCM 将服务标记为超时,因为初始启动时间超过 30 秒。我无法更改注册表设置以增加启动时间。我怀疑在这种情况下不应多次调用主入口点。
【问题讨论】:
-
如果你的循环时间太长,你不能把所有的东西都移到一个工人身上,然后只用服务启动代码:启动工人吗?
-
顺便说一句;你说“windows服务”层有5个服务;这意味着您应该期望该 exe 被调用 5 次 - 每个逻辑服务一次 - 这就是问题所在吗?
-
是的,马克,这就是问题所在。主入口点应该只执行一次。这是我的假设,但每次 SCM 尝试启动服务时都会调用它。所有 5 个服务共享同一个 exe
-
那么正如我已经说过的(评论和回答),这里的问题是您的期望不正确。他们共享一个 exe 的事实是无关紧要的;事实上,在许多情况下,使用同一个 exe 来表示同一个软件的不同命名实例是很常见的。他们使用相同的 exe 的事实没关系;它们本质上是不同的服务,并且将独立启动。如果您只希望它启动一次,则只需将其注册为一项服务。