如何在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服务设置为在服务控制器中自动重新启动,因此我可以处理服务每天重新启动一到两次的问题,但如果可以的话,我宁愿阻止它。
这不是一个真正的答案,更多的是一个注释,但我讨厌注释中代码格式的糟糕。
你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是否报告了任何错误。这通常会提供关于进程死亡原因的有用信息。