林不知道这是这类问题的正确论坛,但我目前正试图找到一个错误,我不能在使用内存转储的Web服务中重现,我想我有一个具体的问题,我需要帮助,我认为有人可能会有一些意见。线程是否可以抛出多个ThreadAbortException异常?
分析使用的WinDbg我发现aprox的内存75000个ThreadAbortExceptions,他们都从这里起源内存转储:
at System.Threading.WaitHandle.WaitOne(Int64 timeout Boolean exitContext)
at MyNameSpace.CustomThreadPool.Run()
它们在一段很短的时期都创造,当应用程序试图卸载它的appdomain(IIS正在关闭)。
我现在无法弄清楚它是如何可能引发这么多的ThreadAbortException?如果一个线程退出,有什么方法可以提高多个?如果任何人都可以提出任何暗示,为什么会有这么多的这种类型的例外存在?从我所看到的最多有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;
}
}
非常感谢那个输入,我不知道Thread.Abort! 但是,我无法在我控制的代码中找到任何用法。框架可以自己做这件事吗? 我看了Respose.Redirect,Response.End和Server.Transfer,但我找不到任何用法。 娱乐是我要去看的东西,谢谢。 – MatteS 2010-06-21 08:35:04
如果每隔x分钟重新创建一个池,从而创建一个新线程,那么最大线程可以存在,还是有可能拥有多达75000个线程?我目前正在看一些代码,可能会建议以定时间隔进行娱乐。 – MatteS 2010-06-21 08:45:16
@MatteS:看我的编辑。我怀疑你有75000线程 - 我怀疑是有什么响应线程中止再次启动它,然后AppDomain.Unload重新中止它等。 – 2010-06-21 08:48:04