如何在Windows服务的后台线程中优雅地处理此异常

本文关键字:处理 异常 线程 Windows 服务 后台 | 更新日期: 2023-09-27 18:21:14

我使用的是C#.NET 4.0。

我有Windows服务。此Windows服务启动一个后台线程。此后台线程对Win32 API进行P/Invoke调用,并且Win32函数将非常间歇地返回垃圾(大约在24小时内一次或两次,间隔1秒)。我尽我所能在不引发异常的情况下处理这些垃圾,但最终还是会发生异常。当它这样做时,它会终止我的服务,即使我正在使用一个捕获异常的try/catch。

using System.Security.Principal;
Thread awesomeThread;
protected override void OnStart(string[] args)
{  
    ThreadStart awesomeThreadThreadStart = new ThreadStart(AwesomeThread);
    awesomeThread = new Thread(awesomeThreadThreadStart);
    awesomeThread.IsBackground = true;
    awesomeThread.Start();
}
private void AwesomeThread()
{
    while (serviceStarted)
    {
         if (serviceStarted)
             Thread.Sleep(1000)
         else
             break;
        //
        // WinApi calls happen here. Once every few hours, they return gibberish.
        //
        NTAccount account = new NTAccount(domain, username);
        SecurityIdentifier sid = null;
        try
        {
             sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));                       
        }
        catch (Exception ex)
        {
             Eventlog.WriteEntry("Oh no an exception occurred: " + ex.Message);
        }
        // Resource cleanup stuff
    }
}

因此,当account.Translate()上确实发生异常时,会捕获异常并写入事件日志消息,此时线程可以安全地继续执行。。。但是.NET杀死了它,从而杀死了我的服务。我可以处理异常并允许后台线程继续执行吗?

目前,作为一种变通方法,我已将Windows服务设置为在服务控制器中自动重新启动,因此我可以处理服务每天重新启动一到两次的问题,但如果可以的话,我宁愿阻止它。

如何在Windows服务的后台线程中优雅地处理此异常

这不是一个真正的答案,更多的是一个注释,但我讨厌注释中代码格式的糟糕。

你100%确定那一句话中的异常是你唯一的问题吗?我建议你在你的程序中添加以下内容:

     // Create AppDomain ProcessExit and UnhandledException event handlers
     AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
     AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

当然,还有事件处理程序:

  /// <summary>
  /// Method called when the process is exiting.
  /// </summary>
  private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
  {
     // do some logging?
  }

  /// <summary>
  /// Method called if an unhandled AppDomain exception occurs.
  /// </summary>
  private static void CurrentDomain_UnhandledException(object sender,
                                                       UnhandledExceptionEventArgs e)
  {
     // do some logging?
  }

此时您无法保存服务,但您可能会获得一些有用的信息。

编辑:

我刚刚注意到,我复制并粘贴了一些代码,其中事件处理程序标记为"静态",但这不是必须的。

检查Windows事件日志,查看进程退出时.NET是否报告了任何错误。这通常会提供关于进程死亡原因的有用信息。