我有一个用C#编写的Windows服务,它产生了几个工作线程。这些线程应该每隔X分钟循环一次,直到服务停止,这在大多数情况下都能正常工作。但是,有一个线程似乎无缘无故停止。我们已经有了一个try / catch块,其中包含了线程整个函数的日志代码,但它从不记录任何异常。
在.NET中,有没有办法监视来自另一个进程的线程并记录何时/为何/如何停止?
产生线程的代码如下所示:
try
{
// Create a new thread for processing Incoming Emails
IncomingEmailThread = new Thread(new ThreadStart(ProcessIncomingEmails));
IncomingEmailThread.Start();
LogEvent("Service Started", EventLogEntryType.Information);
}
catch (Exception e)
{
LogEvent(e.Message, EventLogEntryType.Error);
}
线程内的代码如下所示:
while (!Closing)
{
try
{
// Wait for 5 minutes before running.
InterruptableSleep.WaitOne(300000, false);
// Process the incoming email for all instances
string[] Instances = Settings.GetAllInstances();
foreach (string Instance in Instances)
{
Logic.IncomingEmail IncomingEmailInstance = new Logic.IncomingEmail(Instance);
IncomingEmailInstance.CreateRecordsFromIncomingEmail();
}
}
catch (Exception ex)
{
// Log the exception and then eat it so it doesn't stop the thread
LogEvent(ex.Message + "\r\n" + ex.StackTrace, EventLogEntryType.Error);
}
}
问题不是由Closing标志引起的,因为此循环通常会在停止工作之前运行几天。问题不是CreateRecordsFromIncomingEmail()内部的异常,因为catch块没有记录任何异常。我们的日志代码直接写入Windows事件日志,我们在整个产品中使用它,它非常可靠。
不幸的是,我们无法使用调试器,因为我们只在一台生产服务器上看到了这个问题。我们无法在开发人员或任何其他服务器上重现它。
答案 0 :(得分:3)
如果你发布了一些代码,包括产生线程的函数,那会有所帮助。 怀疑导致多种可能的解释
你的线程不再存在,因为它卡在一些锁中。仔细检查(如果有的话)所有锁定指令并注意数据库事务
我遇到类似的问题,一个线程从未在Mono中开始,在类似于你的场景中。
但是,如果你有这样的代码:
{
Thread t = new Thread(Method);
t.Start();
Run = true;
}
void Method()
{
while(Run)
{ ... }
}
那么你可能会遇到问题,具体取决于你设置Run = true的位置。在这种情况下,在Start()
之后,您可能会认为花费一些时间让线程到达其控制点,但实际上并非如此。
如果没有关于代码的进一步信息,我可能会从你的描述中想象你有这样的问题(可以处理ThreadAbortException或ThreadInterruptException来记录但最终会传播,所以情况并非如此)
您询问了如何调试:使用Visual Studio,您可以“连接到进程”并附加到正在运行的进程,获取线程列表等等。
答案 1 :(得分:0)
你确定它是你的一个工作线程正在停止吗? (与计时器线程或其他东西相反)
答案 2 :(得分:0)
附上调试器并查看。
答案 3 :(得分:0)
在Visual Studio 2008中,如果在调试时暂停应用程序,则可以选择Debug - > Windows - >线程(或点击 Ctrl + Alt + H )查看当前正在执行的线程。
从那里你可以双击一个线程,看看它目前在哪里。这可能表明,例如,您的帖子在调用Monitor.Enter
或WaitHandle.WaitOne
或类似内容时是否已陷入僵局。
此外,如果你的帖子已经真的退出了,至少你可以通过看到它在列表中不存在来确认。
答案 4 :(得分:0)
也许您的日志记录有异常,您无法记录它们。添加另一种日志机制。临时邮件每个例外你自己。
如果您登录到文件系统,请检查您的服务用户对文件系统的写入权限。
答案 5 :(得分:0)
您是否考虑过使用AppDomain.UnhandledException事件注册处理程序?
答案 6 :(得分:0)
我们从来没有找到解决方案,但问题停止了。我们决定只添加一些日志代码,以防它再次发生。