Frage

Im nicht sicher, dann ist dies das richtige Forum für diese Art von Frage, aber ich bin zur Zeit versucht, einen Fehler zu finden ich in einem Web-Dienst mit einem Speicherabbild reproduzieren kann nicht und ich glaube, ich habe eine spezifische Frage, die ich brauche Hilfe mit, dass ich glaube, jemand könnte etwas Eingang hat auf.

Die Analyse ein Speicherabbild mit WinDbg ich ca. 75000 Threadabortexceptions im Speicher finden, und sie alle von hier stammen:

at System.Threading.WaitHandle.WaitOne(Int64 timeout  Boolean exitContext)
at MyNameSpace.CustomThreadPool.Run()

Sie sind alle in einem sehr kurzen Zeitraum erstellt, wenn die Anwendung versucht, seine Appdomain zu entladen (IIS schließt nach unten).

Was ich kann jetzt herauszufinden, ist, wie sein mögliches so viele Threadabortexceptions zu erhöhen? Wenn ein Thread beendet wird, ist es eine Möglichkeit, mehr als eine erhöhen kann? Wenn jemand irgendeinen Hinweis geben, warum so viele Ausnahmen von dieser Art existieren kann? Von dem, was ich kann es etwa 20 Fäden sehen max ist dieser Prozess, und die Thread selbst hat nur eine (!) Thread, wenn dies der Fall ist.

Die CustomThreadPool Klasse kommt aus diesem Artikel: 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;
    }
}
War es hilfreich?

Lösung

Es ist möglich, zu fangen und dann setzen Sie eine ThreadAbortException mit Thread.ResetAbort . So ein einzelner Thread tatsächlich viele solche Ausnahmen geworfen auf sie haben könnte.

Zum Beispiel, wenn Sie Response.Redirect(url, true) in ASP.NET aufrufen, wird es den aktuellen Thread abbrechen und dann brechen Sie den Abbruch höher.

Ich bin nicht sicher, dass dies ganz erklärt Ihre Situation, aber es ist ein Blick wert. Alternativ versucht, etwas den Thread-Pool zu erstellen, wenn es „abstürzt“ aufgrund der Anwendungsdomäne entladen wird?

EDIT: So reagieren Sie auf Ihren Kommentar: nach der AppDomain.Unload Dokumentation:

  

Die Fäden in der Domäne sind beendet   Verwendung der Abort-Methode, die eine wirft   Thread im Gewinde.   Obwohl sollte der Faden beenden   prompt, kann es weiterhin Ausführung   für eine unvorhersagbare Zeitspanne, in   eine finally-Klausel.

Grundsätzlich sind die Fäden gerade abgebrochen werden, weil Ihr Appdomain entladen wird.

Andere Tipps

Doing ein Response.Redirect ( "~ / Somewhere.aspx") verursacht manchmal eine Threadabort, wenn der aktuelle (Standard) Thread noch nicht fertig Ausführung hat.

Sie können dies verhindern, indem die überladene Redirect-Methode.

Response.Redirect("~/Somewhere.aspx", false);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top