Welcome

首页 / 软件开发 / .NET编程技术 / .Net下跟踪线程挂起和程序死循环

.Net下跟踪线程挂起和程序死循环2011-10-15 博客园 Eaglet.Net 下的程序调试相对C/C++要简单很多,少了那些令人头疼的指针越界的问题。不过当你的程序遇 到如下问题时,依然非常棘手:

1. 进程异常终止。解决方案见 .Net 下未捕获异常的处理

2. 内存泄漏或者内存申请后程序始终没有释放。解决方案见 用 .NET Memory Profiler 跟踪.net 应 用内存使用情况--基本应用篇 。如果通过自己编写的程序监控,我将在以后的文章中阐述。

3. 线程因未知原因挂起,比如死锁。

4. 程序死循环。

本文将阐述如果编写程序对后两者故障实时跟踪并报告。

首先我们需要一个单独的监控线程来监控需要监控的线程

我做了一个监控类 ThreadMonitor,在开始监控之前,我们将监控线程的优先级设置为最高。

public ThreadMonitor()
{
_MonitorThread = new Thread(new ThreadStart(MonitorTask));
_MonitorThread.Priority = ThreadPriority.Highest;
_MonitorThread.IsBackground = true;

}

接下来我们为这个线程提供几个公共方法

Start 方法让调用者启动监控

Register 方法用于将需要监控的线程注册到监控列表中

Heartbeat 方法后面说明

/**//// <summary>
/// Start monitor
/// </summary>
public void Start()
{
_MonitorThread.Start();
}


/**//// <summary>
/// Monitor register
/// </summary>
/// <param name="monitorPara">Monitor parameter</param>
public void Register(MonitorParameter monitorPara)
{
Debug.Assert(monitorPara != null);
Debug.Assert(monitorPara.Thread != null);

if (GetTCB(monitorPara.Thread) != null)
{
throw new System.ArgumentException("Register repeatedly!");
}

lock (_RegisterLock)
{
_TCBTable.Add(monitorPara.Thread.ManagedThreadId, new TCB (monitorPara));
}
}

public void Heartbeat(Thread t)
{
TCB tcb = GetTCB(t);
if (tcb == null)
{
throw new System.ArgumentException("This thread was not registered!");
}

tcb.LastHeartbeat = DateTime.Now;
tcb.HitTimes = 0;
tcb.Status &= ~ThreadStatus.Hang;
}