Windows服务刚刚停止。没有消息,没有警报,错误,警告 - 什么都没有

时间:2013-09-04 21:33:02

标签: windows-services system.reactive reactive-programming

我有一个Windows服务,只是默默地自行停止。以下是相关代码:

OnStart()方法:

    protected override void OnStart(string[] args)
    {
        try
        {
            InitializeLogging();

            // we don't DO command line arguments
            if (args.Length > 0)
            {
                eventLog.WriteEntry("All command line arguments are ignored.  You must edit the app.config file manually to make changes to what watchers are run.");
                throw new ArgumentException("Command line arguments are ignored.");
            }

            ReadAppConfig();
            RecalculateStartTimes();
            InitializeWatchers();

        }
        catch (Exception e)
        {
            eventLog.WriteFormattedEntry("Error on Start: {0}", e.Message);
        }
        finally
        {
            eventLog.WriteEntry("Service start completed");
        }
    }

OnStop()方法:

    protected override void OnStop()
    {
        eventLog.WriteEntry("Service stopped.");
    }

InitializeWatchers()方法:

    private void InitializeWatchers()
    {
        try
        {

            var watchers = _watcherSection.Watchers.ToList<WatcherElement>();

            eventLog.WriteEntry(string.Format("Initializing {0} watchers.", watchers.Count()));

            var obsWatchers = watchers.ToObservable();
            obsWatchers.SelectMany(
                watcher =>
                    Observable.Timer(watcher.StartTime, TimeSpan.FromHours(watcher.Interval))
                              .SelectMany(
                                    Observable.FromAsync(
                                      async () => new
                                      {
                                          watcher,
                                          response = await CheckFolder(watcher.Path)
                                      })))
                              .Subscribe(
                                    onNext: x =>
                                    {
                                        eventLog.WriteFormattedEntry("\nWatcher: {0}, Time:{1}", x.watcher.Name, DateTimeOffset.Now);
                                        if (x.response.Success)
                                            eventLog.WriteFormattedEntry("| Success!\n| Value: '{0}'\n| Message: {0}", x.response.Value, x.response.Message);
                                        else
                                            eventLog.WriteFormattedEntry("| FAILURE!\n| Value: '{0}'\n| Message: {0}\n| Errors: '{0}'", x.response.Value, x.response.Message, x.response.Exceptions.First());
                                    },
                                    onError: e =>
                                        {
                                            var err = e;
                                            var sb = new StringBuilder();
                                            sb.AppendLine("The observer threw an error:")
                                              .AppendFormatLine("| Message: {0}", e.Message);

                                            while (e.InnerException != null)
                                            {
                                                sb.AppendFormatLine("| Inner: {0}", e.InnerException.Message);
                                                e = e.InnerException;
                                            }

                                            sb.AppendLine();
                                            eventLog.WriteEntry(sb.ToString());
                                            throw err;
                                        });

            eventLog.WriteEntry("about to wait.");
            obsWatchers.Wait();
            eventLog.WriteEntry("passed the wait");
        }
        catch (Exception e)
        {
            eventLog.WriteFormattedEntry("Exception thrown in InitializeWatchers(WatchersSection): {0}", e.Message);
            throw;
        }
    }

运行此代码时,服务正常启动。事件日志记录了三个事件:

  1. 服务&amp;记录已开始。
  2. 初始化1名观察员。
  3. 服务开始完成。
  4. ......它停止了。我必须手动刷新“服务”窗口,但它会退出运行。我没有收到任何错误,也没有任何其他eventLog条目。

    令人沮丧的是,此代码完美地用作控制台应用程序。我已将所有eventLog.WriteEntry()更改为Console.WriteLine(),但除此之外,代码是相同的并且按预期执行。

    任何智慧都会受到赞赏。

2 个答案:

答案 0 :(得分:1)

我怀疑服务控制管理器正在终止您的服务,因为它没有在超时窗口(30秒,IIRC)内从OnStart返回。

我在managed service basics上发布了一篇基于blog entry by the BCL team的博文。请注意,MSDN文档不足;您必须知道BCL团队博客文章中的信息才能正确编写托管服务。

答案 1 :(得分:0)

而不是使用obsWatchers.Wait()阻止并导致Stephen所说的问题,而不是异步订阅。

将此属性添加到您的班级:

private SingleAssignmentDisposable _subscription = new SingleAssignmentDisposable();

将此添加到您的OnStop方法:

_subscription.Dispose();

InitializeWatchers()中,取消对Subscribe的嵌套调用,并通过调用subscribe替换obsWatchers.Wait(),如下所示:

private void InitializeWatchers()
{
    try
    {

        var watchers = _watcherSection.Watchers.ToList<WatcherElement>();

        eventLog.WriteEntry(string.Format("Initializing {0} watchers.", watchers.Count()));

        var obsWatchers = watchers.ToObservable();
        _subscription.Disposable = obsWatchers
            .SelectMany(watcher => Observable
                .Timer(watcher.StartTime, TimeSpan.FromHours(watcher.Interval))
                .SelectMany(_ => Observable.FromAsync(async () => new
                      {
                          watcher,
                          response = await CheckFolder(watcher.Path)
                      })))
             .Subscribe(
                 onNext: x =>
                 {
                     eventLog.WriteFormattedEntry("\nWatcher: {0}, Time:{1}", x.watcher.Name, DateTimeOffset.Now);
                     if (x.response.Success)
                         eventLog.WriteFormattedEntry("| Success!\n| Value: '{0}'\n| Message: {0}", x.response.Value, x.response.Message);
                     else
                         eventLog.WriteFormattedEntry("| FAILURE!\n| Value: '{0}'\n| Message: {0}\n| Errors: '{0}'", x.response.Value, x.response.Message, x.response.Exceptions.First());
                 },
                 onError: e =>
                 {
                     var err = e;
                     var sb = new StringBuilder();
                     sb.AppendLine("The observer threw an error:")
                       .AppendFormatLine("| Message: {0}", e.Message);

                     while (e.InnerException != null)
                     {
                         sb.AppendFormatLine("| Inner: {0}", e.InnerException.Message);
                         e = e.InnerException;
                     }

                     sb.AppendLine();
                     eventLog.WriteEntry(sb.ToString());
                     throw err;
                 });
        eventLog.WriteEntry("passed the wait");
    }
    catch (Exception e)
    {
        eventLog.WriteFormattedEntry("Exception thrown in InitializeWatchers(WatchersSection): {0}", e.Message);
        throw;
    }
}