繁体   English   中英

TopShelf服务无法启动

[英]TopShelf Service does not start

我有一个使用TopShelf的.NET Console应用程序将此应用程序作为Windows服务运行。 控制台应用程序本身在运行和执行应做的事情时都没有问题。 我已经安装了TopShelf nuget软件包,并且已经正确配置了TopShelf(据我所知)。

当我调试应用程序时,甚至将应用程序安装到Windows服务中并启动该服务之后,它似乎都没有执行方法“ DoUpdate”,而该方法我已定义了在经过的事件中要执行的计时器。 但这没有发生。 有任何线索吗?

这是控制台应用程序中我的主要方法:

    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();
    }

这是完成工作的类:

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更改为许多不同的持续时间。 但这似乎从未被调用过。

我可以确认计时器对象的“间隔”属性确实已设置。 我还可以确认此服务已安装在Windows Service中并且正在运行。 正如我所说,我试图通过调试包括TopShelf在内的整个应用程序以及在将其作为服务构建并安装后进行测试。 我不知道为什么计时器经过的事件处理程序(DoUpdate)无法触发。

经过艰苦的谷歌搜索答案,我终于明白了。 万一别人有同样的问题,这就是我所做的。 我在计时器对象上缺少几个设置。 在Start()方法中,我设置了计时器对象的AutoReset和Enabled属性。 通过此修改,它现在将触发ElapsedTime事件,并且该应用程序将按预期运行。

这是我修改的代码:

            updateTimer.Elapsed += new ElapsedEventHandler(DoUpdate);
            updateTimer.AutoReset = true;
            updateTimer.Enabled = true;

您正在设置计时器的Interval属性并将事件分配给Elapsed-但您永远不会启动计时器。 这就是为什么Elapsed不会触发。

调用updateTimer.Start()或设置updateTimer.Enabled = true

正如Enabled的文档所述:

如果Timer应该引发Elapsed事件,则为true否则为true 否则为false 默认值为false

对于开始:

通过将Enabled设置为true,开始引发Elapsed事件。

Topshelf文档还显示您必须启动计时器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM