Im не уверен, что это правильный форум для этого типа вопросов, но Im в настоящее время пытается найти ошибку, которую я не могу воспроизвести в веб-службе, используя дамп памяти, и я думаю, что у меня есть конкретный вопрос, в котором мне нужна помощь, что я подумайте, что у кого-то может быть некоторый вклад.Может ли поток когда-либо бросать больше одного ThreadAbortException?
Анализ дампа памяти с помощью WinDbg я нахожу приблиз 75000 ThreadAbortExceptions в памяти, и все они происходят здесь:
at System.Threading.WaitHandle.WaitOne(Int64 timeout Boolean exitContext)
at MyNameSpace.CustomThreadPool.Run()
Все они созданы в течение очень короткого периода времени, когда приложение пытается выгрузите его appdomain (IIS закрывается).
Что я не могу понять сейчас, так это, как можно увеличить столько ThreadAbortExceptions? Если поток завершает работу, есть ли способ, который может вызвать более одного? Если кто-нибудь может дать какой-либо намек на то, почему так много исключений такого типа могут существовать? Из того, что я вижу, существует около 20 потоков max, это процесс, и сам threadpool имеет только один (!) Поток, когда это происходит.
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
Если бассейн был воссоздан каждые x минут, например, и, тем самым, новый поток, не существует ли максимум потоков, которые могут существовать, или возможно иметь целых 75000 потоков? В настоящее время я просматриваю код, который может предполагать воссоздание с временными интервалами. – MatteS
@MatteS: Смотрите мое редактирование. Я сомневаюсь, что у вас будет 75000 потоков - мое подозрение в том, что что-то реагирует на поток, прерывая его, снова запустив его, а затем AppDomain.Unload повторно отменяет его и т. Д. –