【发布时间】:2014-09-08 12:44:30
【问题描述】:
我正在使用 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 服务设置为在服务控制器中自动重启,因此我可以处理服务每天重启一到两次,但如果可以的话,我宁愿阻止它。
【问题讨论】:
-
您可能希望在 while 循环中的所有内容中都使用 try catch。此外,我通常会使用 .ToString() 方法而不是 .Message 来记录异常。您将获得有关异常的更多详细信息。除此之外,请确保使用要部署的 dll/exe 部署 pdb 文件,以确保异常详细信息中包含行号。如果未捕获异常,是否有可能您没有尝试捕获您需要的所有内容?
-
@ColeW 感谢您的反馈,但我已经知道确切的异常是什么——我不需要更多关于异常是什么、发生位置或发生原因的详细信息。该异常仅发生在我包含在 try 块中的单个语句中。我不明白的是,为什么即使我捕获了异常,在 catch 块中的代码运行之后,线程和整个进程仍然终止。
-
我们在使用一个非常大的 ERP 系统应用程序提供商的第三方库时遇到了类似的情况。突然发生了一个错误,无法捕获,但会记录在事件日志中。之后,服务就退出了。在尝试解决了许多不成功的小时后,我们提供了第二个服务,它只监视并重新启动第一个服务。这可能无法解决您的问题,但也许您不再感到孤单……
标签: c# .net multithreading exception-handling