TopShelf 服务未启动
TopShelf Service does not start
我有一个使用 TopShelf 的 .NET 控制台应用程序 运行 此应用程序作为 windows 服务。控制台应用程序本身 运行 没有问题,并且可以做它应该做的事情。我安装了 TopShelf nuget 包并正确配置了 TopShelf(据我所知)。
当我调试应用程序时,甚至在我将应用程序安装到 Windows 服务并启动服务后,它似乎没有执行方法 "DoUpdate" 我已经定义了要执行的计时器在过去的事件中。但它没有发生。有任何线索吗?
这是我在控制台应用程序中的 Main 方法:
public static void Main()
{
try
{
HostFactory.Run(x =>
{
x.Service<DNSUpdateTopShelf>(a =>
{
a.ConstructUsing(n => new DNSUpdateTopShelf());
a.WhenStarted(ts => ts.Start());
a.WhenStopped(ts => ts.Stop());
});
x.SetDescription("Update GoDaddy DNS Records");
x.SetDisplayName("GoDaddy DNS Updater");
x.SetServiceName("GoDaddyDNSUpdate");
//x.RunAsNetworkService();
x.RunAsLocalSystem();
x.StartAutomatically();
});
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
System.Console.WriteLine("---------------");
System.Console.ReadKey();
}
这里是 Class 做的工作:
public class DNSUpdateTopShelf
{
private System.Timers.Timer updateTimer;
private int interval;
private EventLog log;
public DNSUpdateTopShelf()
{
Initialize();
}
public void Initialize()
{
//log = new EventLog("DynaProLogs");
updateTimer = new System.Timers.Timer();
}
public void Start()
{
try
{
Utils.WriteLog("In Start Method");
var jsonFile = $"{Directory.GetCurrentDirectory()}\appconfig.json";
using (StreamReader r = new StreamReader(jsonFile))
{
var json = r.ReadToEndAsync().Result;
var config = (JObject)JsonConvert.DeserializeObject(json);
interval = config["interval"].Value<int>();
}
updateTimer.Interval = interval;
updateTimer.Elapsed += new ElapsedEventHandler(DoUpdate);
}
catch (Exception ex)
{
Utils.WriteLog($"DNSUpdater - {ex.Message}", type: EventLogEntryType.Error);
throw;
}
}
public void Stop()
{
Utils.WriteLog("In Stop Method");
updateTimer.Stop();
}
public void DoUpdate(object sender, ElapsedEventArgs e)
{
Utils.WriteLog("In DoUpdate method");
DNSUpdater updater = new DNSUpdater();
var results = Task.Run( async () => await updater.UpdateAllDomainIPAsync()).Result;
//var results = updater.UpdateAllDomainIPAsync().Result;
foreach (UpdateResult result in results)
{
Utils.WriteLog($"{result.RequestURI} -- {result.Message}");
}
}
}
问题是:DoWork 方法从未被调用过。我已将计时器的 ElapsedTime 更改为许多不同的持续时间。但它似乎从来没有被调用过。
我可以确认计时器对象的 "Interval" 属性 确实已设置。我还可以确认此服务已安装在 Windows 服务中并且正在 运行ning。正如我所说,我尝试通过调试包括 TopShelf 在内的整个应用程序以及在将其构建和安装为服务后对其进行测试。我不明白为什么计时器已用事件处理程序 (DoUpdate) 没有触发。
经过艰苦的谷歌搜索,我终于找到了答案。如果其他人遇到同样的问题,这就是我所做的。我缺少计时器对象的几个设置。在我的 Start() 方法中,我设置了计时器对象的 AutoReset 和 Enabled 属性。通过此修改,它现在触发 ElapsedTime 事件并且应用程序按预期工作。
这是我修改后的代码:
updateTimer.Elapsed += new ElapsedEventHandler(DoUpdate);
updateTimer.AutoReset = true;
updateTimer.Enabled = true;
您正在设置计时器的间隔 属性 并将事件分配给 Elapsed - 但您从未启动计时器。这就是 Elapsed 不触发的原因。
呼叫updateTimer.Start() or set updateTimer.Enabled = true.
正如 Enabled 的文档所说:
true
if the Timer should raise the Elapsed event; otherwise, false
. The default is false
.
开始:
Starts raising the Elapsed event by setting Enabled to true.
Topshelf docs也显示你必须启动定时器。
我有一个使用 TopShelf 的 .NET 控制台应用程序 运行 此应用程序作为 windows 服务。控制台应用程序本身 运行 没有问题,并且可以做它应该做的事情。我安装了 TopShelf nuget 包并正确配置了 TopShelf(据我所知)。
当我调试应用程序时,甚至在我将应用程序安装到 Windows 服务并启动服务后,它似乎没有执行方法 "DoUpdate" 我已经定义了要执行的计时器在过去的事件中。但它没有发生。有任何线索吗?
这是我在控制台应用程序中的 Main 方法:
public static void Main()
{
try
{
HostFactory.Run(x =>
{
x.Service<DNSUpdateTopShelf>(a =>
{
a.ConstructUsing(n => new DNSUpdateTopShelf());
a.WhenStarted(ts => ts.Start());
a.WhenStopped(ts => ts.Stop());
});
x.SetDescription("Update GoDaddy DNS Records");
x.SetDisplayName("GoDaddy DNS Updater");
x.SetServiceName("GoDaddyDNSUpdate");
//x.RunAsNetworkService();
x.RunAsLocalSystem();
x.StartAutomatically();
});
}
catch (Exception e)
{
System.Console.WriteLine(e.Message);
}
System.Console.WriteLine("---------------");
System.Console.ReadKey();
}
这里是 Class 做的工作:
public class DNSUpdateTopShelf
{
private System.Timers.Timer updateTimer;
private int interval;
private EventLog log;
public DNSUpdateTopShelf()
{
Initialize();
}
public void Initialize()
{
//log = new EventLog("DynaProLogs");
updateTimer = new System.Timers.Timer();
}
public void Start()
{
try
{
Utils.WriteLog("In Start Method");
var jsonFile = $"{Directory.GetCurrentDirectory()}\appconfig.json";
using (StreamReader r = new StreamReader(jsonFile))
{
var json = r.ReadToEndAsync().Result;
var config = (JObject)JsonConvert.DeserializeObject(json);
interval = config["interval"].Value<int>();
}
updateTimer.Interval = interval;
updateTimer.Elapsed += new ElapsedEventHandler(DoUpdate);
}
catch (Exception ex)
{
Utils.WriteLog($"DNSUpdater - {ex.Message}", type: EventLogEntryType.Error);
throw;
}
}
public void Stop()
{
Utils.WriteLog("In Stop Method");
updateTimer.Stop();
}
public void DoUpdate(object sender, ElapsedEventArgs e)
{
Utils.WriteLog("In DoUpdate method");
DNSUpdater updater = new DNSUpdater();
var results = Task.Run( async () => await updater.UpdateAllDomainIPAsync()).Result;
//var results = updater.UpdateAllDomainIPAsync().Result;
foreach (UpdateResult result in results)
{
Utils.WriteLog($"{result.RequestURI} -- {result.Message}");
}
}
}
问题是:DoWork 方法从未被调用过。我已将计时器的 ElapsedTime 更改为许多不同的持续时间。但它似乎从来没有被调用过。
我可以确认计时器对象的 "Interval" 属性 确实已设置。我还可以确认此服务已安装在 Windows 服务中并且正在 运行ning。正如我所说,我尝试通过调试包括 TopShelf 在内的整个应用程序以及在将其构建和安装为服务后对其进行测试。我不明白为什么计时器已用事件处理程序 (DoUpdate) 没有触发。
经过艰苦的谷歌搜索,我终于找到了答案。如果其他人遇到同样的问题,这就是我所做的。我缺少计时器对象的几个设置。在我的 Start() 方法中,我设置了计时器对象的 AutoReset 和 Enabled 属性。通过此修改,它现在触发 ElapsedTime 事件并且应用程序按预期工作。
这是我修改后的代码:
updateTimer.Elapsed += new ElapsedEventHandler(DoUpdate);
updateTimer.AutoReset = true;
updateTimer.Enabled = true;
您正在设置计时器的间隔 属性 并将事件分配给 Elapsed - 但您从未启动计时器。这就是 Elapsed 不触发的原因。
呼叫updateTimer.Start() or set updateTimer.Enabled = true.
正如 Enabled 的文档所说:
true
if the Timer should raise the Elapsed event; otherwise,false
. The default isfalse
.
开始:
Starts raising the Elapsed event by setting Enabled to true.
Topshelf docs也显示你必须启动定时器。