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

时间:2014-09-08 12:44:30

标签: c# .net multithreading exception-handling

我正在使用C#.NET 4.0。

我有一个Windows服务。此Windows服务会旋转后台线程。这个后台线程使得对Win32 API的P / Invoke调用非常间歇性地(在24小时内以1秒的间隔一次或两次的顺序),Win32函数将返回垃圾。我尽力尝试处理这些垃圾而不引发异常,但最终会发生异常。当它发生时,即使我使用捕获异常的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服务设置为在服务控制器中自动重启,因此我可以处理服务每天重启一次或两次,但如果可以,我宁愿阻止它。 / p>

2 个答案:

答案 0 :(得分:2)

这不是一个真正的答案,更多的是评论,但我讨厌评论中代码格式不佳。

您是否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?
  }

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

编辑:

注意到我复制并粘贴了一些代码,其中事件处理程序已标记为&#34;静态&#34;,但这并非必要。

答案 1 :(得分:0)

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