【问题标题】:windows service strange behaviorwindows服务奇怪的行为
【发布时间】:2013-02-26 18:16:17
【问题描述】:

我使用eventLogFileSystemWatcher 实现了Windows 服务,它查找特定目录中的更改并将消息写入MyLog

奇怪的事情 1:
我通过 installUtil.exe 安装它(因为 VS2012 没有安装程序模板),在某些情况下,当我转到“服务”并启动我得到的服务时:

本地计算机上的 [服务名称] 服务启动然后停止。如果某些服务没有被其他服务或程序使用,它们会自动停止。

我已经看过this question。这篇文章的 2 个答案为什么会这样:

1) 没有以OnStart() 方法启动的线程。
我使用设计器并在“属性”窗口中设置了大部分属性,我从未手动启动任何线程,但在某些情况下一切正常,所以我认为情况并非如此。

2) OnStart() 方法发生异常。我认为情况并非如此,因为我没有更改代码。我只是卸载、构建并再次安装相同的服务,在某些情况下它会运行,在某些情况下不会。

当我被这个东西卡住 mabby 2 小时时,我注意到 eventLogSource 属性太长:“FilesMonitoringServices”。我将其更改为“MonitorSource”,一切都开始工作了。比我重新安装它几次并得到与上述相同的警告。我再次更改了Source 属性,现在服务运行了。
这是第一个奇怪的事情。

奇怪的事情 2: 更糟。即使它运行它也只记录 OnStart()OnStop() 方法,我的意思是 fileSystemWatcher 事件处理程序永远不会执行。这很奇怪,因为今天我重新安装了这个服务 mabby 一百次和 3 次它正在工作,但是在我再次重新安装它之后它停止了。而且我根本没有更改重新安装之间的代码。

这是我的类(MonitoringService)中继承ServiceBase的方法和构造函数:

public MonitoringService()
    {
        InitializeComponent();

        if (!EventLog.SourceExists(eventLog.Source))
        {
            EventLog.CreateEventSource(eventLog.Source, eventLog.Log);
        }
        // haven't changed it between the reinstallations
        fileWatcher.Path = @"path";                
    }

protected override void OnStart(string[] args)
    {
        fileWatcher.EnableRaisingEvents = true;
        eventLog.WriteEntry("start", EventLogEntryType.Information);
        base.OnStart(args);
    }

    protected override void OnStop()
    {
        fileWatcher.EnableRaisingEvents = false;
        fileWatcher.Dispose();
        eventLog.WriteEntry("stop", EventLogEntryType.Information);
        base.OnStop();
    }

和文件系统观察者事件处理程序:

private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
    {
        using (var conn = new SqlConnection(GetConnectionString()))
        {
            conn.Open();
            var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value);
            const string cmd = "UPDATE Products SET ImageModifiedDate=@date WHERE ProductId=@productId";
            using (var command = new SqlCommand(cmd, conn))
            {
                command.Parameters.AddWithValue("@productId", productId);
                command.Parameters.AddWithValue("@date", DateTime.Now);
                command.ExecuteNonQuery();
            }                   
        }
        eventLog.WriteEntry(string.Format("{0} has been changed: {1}", e.Name, DateTime.Now), EventLogEntryType.Information);             
    }

问题:在我看来,这种行为不是由我的代码引起的,而是由操作系统设置引起的。可以吗?

****编辑:刚刚发现了更具体的东西:**

1)如果显示信息(当我要启动服务时):

The [service name] service on local computer started and then stopped. ....

我需要更改eventLogSource 属性,重建并重新安装。并且此消息不会出现; mabby 下次再来。

2) 我有以下文件夹层次结构:images/prod-imagesimagesprod-images 目录都包含图像文件。当服务正在运行并且我从prod-images 文件夹更改图像时,消息将按照我的需要写入日志并更新数据库。但在此事件发生后,服务停止! (我检查了 3 次)。当我重新启动它并再次重复几次时,它会更新数据库,写入日志并在 3d 时间得到

The [service name] service on local computer started and then stopped. ....

但这不是最好的部分)如果我更改images 目录中的图像,我可以多次更改并且服务不会停止。 (只有来自images/prod-images 的图像绑定到数据库中的条目)。

那么,这个特性不知何故是指数据库访问?

编辑 2: 在 Visual Studio 中,我使用 DEBUG -> Attach to Process 来调试服务。我设置了断点并更改了图像。事件处理程序第一次完美执行:更新数据库并写入日志消息。但是我继续按 F11(Step Into),这个事件处理程序第二次执行。在行

var productId = Convert.ToInt32(Regex.Match(e.Name, @"\d+").Value); 

我得到“FormatException 未处理”。在此之后我停止调试并且服务停止!就是这样:异常发生在事件处理程序中。

你知道它为什么会第二次执行吗?谢谢!

P.S.我已经提交了 Davut Gürbüz 的答案,因为他指出了我正确的方向。
无论如何,请查看我自己的答案来解释实际问题。

【问题讨论】:

  • 这是错字吗? eventLog.EnableRaisingEvents = true; 而不是 fileWatcher.EnableRaisingEvents = true;
  • 是的,打错了,抱歉

标签: c# .net windows-services


【解决方案1】:

如果你得到启动-停止错误,这意味着你在构造函数中有一个错误。

在你的ctor中加入try catch。您可以将错误记录到 catch 块中的 eventlog 中。

除此之外,我创建了一个 main 方法并将 win 服务作为控制台应用程序启动。如果我在我的 main 方法中获得一个服务实例,我也可以调试它。

//You should select Console Application from Application properties
static void Main(string[] args)
    {
        MyWindowsService service = new MyWindowsService();

        if (Environment.UserInteractive)
        {
            service.OnStart(args);
            Console.WriteLine("Press any key to stop program");
            Console.Read();
            service.OnStop();
        }
        else
        {
            ServiceBase.Run(service);
        }

    } 

希望有帮助

【讨论】:

  • 现在我没有收到启停错误。该服务在我更改图像后立即停止(并且日志中没有条目,并且数据库未更新)。我尝试在 ctor、OnStart 和 OnStop 方法中添加 try/catch 块并将异常记录到 MyLog 中 - 不起作用。服务像以前一样停止。
  • 所以只做我的第二个选项,使用 win 服务作为控制台应用程序,在 main 方法中创建服务和 console.readkey 不退出 main。通过这种方式,您可以将 win 服务作为控制台应用程序运行。然后测试它出了什么问题。
  • Windows 事件日志中是否有任何错误?即使他们通常不会显示确切的原因,所以只需将其作为控制台应用程序启动即可。也许你处理了一个物体并试图到达,错过了一个计时器开始,......很多事情都可能导致
  • 我调试了服务并在事件处理程序中出现异常。请检查更新后的帖子。
  • 您似乎收到了错误stackoverflow.com/a/1865798/413032。除此之外,我认为您没有处理错误,因此服务停止。如果您处理错误发生的位置,则不能停止。
【解决方案2】:

fileSystemWatcher1_Changed 事件处理程序方法执行两次的原因是因为我正在监视 images 文件夹包含的子目录。这个事件处理程序正在监视所有LastWrite 事件。

因此,当我更改 images/prod-images 目录中的图像时,此处理程序对图像更改以及文件夹更改做出了反应。

在这种情况下,我可以将监控路径更改为prod-images,或者在更新数据库时插入if 语句。

这么愚蠢的错误我花了几天时间才发现))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 2014-04-24
    • 1970-01-01
    • 2012-02-09
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多