TopShelf服务无法启动

时间:2018-08-12 19:21:05

标签: .net windows-services topshelf

我有一个使用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更改为许多不同的持续时间。但这似乎根本没有被调用。

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

2 个答案:

答案 0 :(得分:0)

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

这是我修改的代码:

select Distinct C.v, F.a
from tbl_main as F
    join tbl_inner1  as C on C.ID = F.ID and c.to = 0 
    join tbl_inner2 as E on E.a = F.a
    join tbl_inner3 as G on G.Id = E.Sales
where F.a = a
  and C.v NOT IN(select v from table_4
                 where Month = DATEPART(month, GETDATE())
                   AND Year = DATEPART(yyyy, GETDATE()))

答案 1 :(得分:0)

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

致电updateTimer.Start()或设置updateTimer.Enabled = true

如“启用”文档中所述:

  

true,如果计时器应引发Elapsed事件;否则为false默认值为false

对于开始:

  

通过将“启用”设置为true,开始引发Elapsed事件。

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