我不确定这是此类问题的正确论坛,但我目前正在尝试使用内存转储查找无法在 Web 服务中重现的错误,并且我认为我有一个需要帮助的特定问题,我认为有人可能有一些输入。
使用 WinDbg 分析内存转储我在内存中发现了 aprox 75000 ThreadAbortExceptions,它们都来自这里:
at System.Threading.WaitHandle.WaitOne(Int64 timeout Boolean exitContext)
at MyNameSpace.CustomThreadPool.Run()
它们都是在很短的时间内创建的,当时应用程序正在尝试卸载其 appdomain(IIS 正在关闭)。
我现在想不通的是怎么可能引发这么多的 ThreadAbortExceptions?如果一个线程退出,有什么方法可以引发多个?如果有人能给出任何提示,为什么会存在这么多这种类型的例外?据我所知,这个进程最多有 20 个线程,发生这种情况时,线程池本身只有一个(!)线程。
CustomThreadPool 类来自这篇文章:http: //msdn.microsoft.com/en-us/magazine/cc163851.aspx
public sealed class CustomThreadPool : IDisposable
{
private Semaphore _workWaiting;
private Queue<WaitQueueItem> _queue;
private List<Thread> _threads;
public CustomThreadPool(int numThreads)
{
if (numThreads <= 0)
throw new ArgumentOutOfRangeException("numThreads");
_threads = new List<Thread>(numThreads);
_queue = new Queue<WaitQueueItem>();
_workWaiting = new Semaphore(0, int.MaxValue);
for (int i = 0; i < numThreads; i++)
{
Thread t = new Thread(Run);
t.IsBackground = true;
_threads.Add(t);
t.Start;
}
}
public void Dispose()
{
if (_threads != null)
{
_threads.ForEach(delegate(Thread t) { t.Interrupt(); });
_threads = null;
}
}
public void QueueUserWorkItem(WaitCallback callback, object state)
{
if (_threads == null)
throw new ObjectDisposedException(GetType().Name);
if (callback == null) throw new ArgumentNullException("callback");
WaitQueueItem item = new WaitQueueItem();
item.Callback = callback;
item.State = state;
item.Context = ExecutionContext.Capture();
lock(_queue) _queue.Enqueue(item);
_workWaiting.Release();
}
private void Run()
{
try
{
while (true)
{
_workWaiting.WaitOne();
WaitQueueItem item;
lock(_queue) item = _queue.Dequeue();
ExecutionContext.Run(item.Context,
new ContextCallback(item.Callback), item.State);
}
}
catch(ThreadInterruptedException){}
}
private class WaitQueueItem
{
public WaitCallback Callback;
public object State;
public ExecutionContext Context;
}
}