C# 未处理Windows服务异常
我有基于ServiceBase类的常规C#服务。此服务加载在启动C++动态链接库上。有时,非托管代码中会发生服务崩溃。不幸的是,事件查看器仅对此进行了非常简短的描述。如果一个人的信息是: 应用程序:StreamMapService.exe 框架版本:v4.0.30319 描述:由于未处理的异常,进程已终止。 异常信息:异常代码c0000005,异常地址00000012” 99%的确定性表明,问题出在非托管代码中。问题是这种情况很少发生(通常一天一次),而且只有在作为服务运行时才会发生。在“调试器”下,一切正常。为了找出问题代码,我以以下方式编辑了我的主方法:C# 未处理Windows服务异常,c#,exception-handling,service,unmanaged,callstack,C#,Exception Handling,Service,Unmanaged,Callstack,我有基于ServiceBase类的常规C#服务。此服务加载在启动C++动态链接库上。有时,非托管代码中会发生服务崩溃。不幸的是,事件查看器仅对此进行了非常简短的描述。如果一个人的信息是: 应用程序:StreamMapService.exe 框架版本:v4.0.30319 描述:由于未处理的异常,进程已终止。 异常信息:异常代码c0000005,异常地址00000012” 99%的确定性表明,问题出在非托管代码中。问题是这种情况很少发生(通常一天一次),而且只有在作为服务运行时才会发生。在“调试器
static void Main()
{
try
{
if (!Environment.UserInteractive)
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
else
{
var services = new Service1();
services.Start();
Console.WriteLine("Press return to exit");
Console.ReadLine();
services.Stop();
}
}
catch (SEHException e)
{
// wrapper for all exceptions having its origin in unmanaged code
StringBuilder sb = new StringBuilder();
sb.AppendFormat("Crash time: {0}\n", DateTime.Now.ToString());
sb.AppendFormat("\nMessage:\n{0}", e.Message);
sb.AppendFormat("\nSource: {0}\n", e.Source);
sb.AppendFormat("Stack trace:\n{0}", e.StackTrace);
sb.AppendFormat("\nTarget site:{0}", e.TargetSite);
SmtpClient client = new SmtpClient("mail.domain.com");
MailAddress from = new MailAddress("sender@domain.com", "sender", System.Text.Encoding.UTF8);
MailAddress to = new MailAddress("receiver@domain.com");
MailMessage message = new MailMessage(from, to);
message.Body = sb.ToString();
message.Subject = "StreamMapService crash info";
client.Send(message);
throw;
}
}
为了测试这个异常处理程序,我在非托管代码的某些部分生成了测试异常。当我在调试器下或从命令行运行服务时,一切正常
我收到一封包含异常信息的电子邮件(最重要的是,它包含非托管异常产生的调用堆栈)
但当我作为系统服务运行这个程序时(从控制面板->管理工具->服务),服务显然崩溃了(它在tcp接口上变得没有响应,并且事件查看器也包含崩溃信息),但我没有收到任何电子邮件
在这种情况下,似乎没有调用异常处理程序。我试图将异常信息写入文件,但也发生了同样的情况
因此,当在调试器下或从命令行运行时,会正确记录调用堆栈信息。当作为系统服务运行时,不会发生任何情况。在这种情况下,异常处理似乎无法正常运行。该异常可能是在另一个线程上引发的。请尝试在代码之前添加以下内容,以便捕获任何nhandled异常:
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
事件处理程序应具有以下签名:
void CurrentDomain_UnhandledException(
object sender, UnhandledExceptionEventArgs e) {
}
打开命令提示符和调试器,以管理员身份运行,然后告知情况。它是否与作为服务运行时的一样。在调试之前,将其框架版本更改为低于或等于3.5。这解决了部分问题。当我更彻底地检查我的调用堆栈时,我发现它不包含非托管方法(我所写的信息不正确,对此表示抱歉)。一段时间后,它意外停止运行。当作为常规exe文件运行或在调试器下运行时,异常处理功能正常。因此未引发事件AppDomain.UnhandledException?请参阅,以获取有关导致此问题的详细信息。因为我使用的是.NET framework 4,所以我尝试添加两个HandleProcessCorruptedStateExceptionons&SecurityCritical属性到“main”和“CurrentDomain\u UnhandledException”方法无效。一切正常。我发现一些异常被允许。