2012-11-13 2 views
5

Ich empfange diesen Fehler in einem Windows-Dienst. Dies ist der gleiche Dienst, die ich vorher in meiner Frage besprochen haben hereFehler beim Entladen der Anwendungsdomäne. (Ausnahme von HRESULT: 0x80131015), in Windows-Dienst

Der Code überarbeitet Parallel.ForEach (meine eigene Version, da dies ein 3.5 Windows-Dienst ist) zu verwenden. Der Grund für die Parallele Verwendung ist auf die Tatsache zurückzuführen, dass es einfach zu lange dauerte, jede Domain zu entladen und parallel laufen zu lassen, sollte sich als schneller erweisen (scheint, obwohl es nur einen Thread gibt, der jedes Unload erledigt ?!).

auf anderen Beiträgen Basierend, kann ich nur vermuten, dass dies irgendwie ist bis auf die Tatsache, dass ich ein ThreadPoolThread zu Unload die AppDomain s verwenden. Ich kann einfach nicht sehen, wie ich es vermeiden kann.

public partial class SomeService : ServiceBase 
{ 
    private Manager _appDomainManager; 

    protected override void OnStop() 
    { 
     _appDomainManager.Dispose(); 
    } 
} 

public class Manager : IDisposable 
{ 
    public void Dispose() 
    { 
     Log.Debug("Disposing"); 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (_disposed) return; 
     if (disposing) 
     { 
      // dispose managed resources 
      Parallel.For(0, appdomains.Length, UnloadAppDomian); 
     } 

     _disposed = true; 
    } 
} 

private UnloadAppDomain(int appDomainIndex); 

public static class Parallel35 
{ 
    public static void For(int start, int end, Action<int> action) 
    { 
     var waitHandles = new WaitHandle[end - start]; 
     for (int j = 0; j < waitHandles.Length; j++) 
     { 
      waitHandles[j] = new ManualResetEvent(false); 
     } 

     for (int i = start; i < end; i++) 
     { 
      int i1 = i - start; 
      ThreadPool.QueueUserWorkItem(
       state => 
       { 
        try 
        { 
         action((int) state); 
        } 
        finally 
        { 
         ((ManualResetEvent) waitHandles[i1]).Set(); 
        } 
       }, i); 
     } 
     WaitHandle.WaitAll(waitHandles); 
    } 
} 
+0

Haben Sie versucht, einen Debugger an Ihren Dienst anzuhängen, um genau zu sehen, wann dies im Fenster "Threads" geschieht? Haben Sie übrigens versucht, alle Anwendungsdomänen in einer einzelnen Hintergrundaufgabe statt in einer Hintergrundaufgabe für jede Anwendungsdomäne zu entladen? –

+0

@PanosRontogiannis das Problem war, wenn ich es in einem einzigen Hintergrund-Thread lief es dauerte einfach zu lange für OnStop zu exeuten. Immer noch mit einigen Argumenten bezüglich des Problems untersucht. –

Antwort

6

Ich fand dies als ein Fehler auf einen der AppDomain s beim Beenden warten auf eine WaitHandle, die nie gesetzt ist.

Wenn ein Thread nicht abgebrochen, zum Beispiel weil er ausführt nicht verwalteten Code, oder weil es einen finally-Block ausgeführt wird, dann nach einen bestimmten Zeitraum ein CannotUnloadAppDomainException im Thread ausgelöst wird, die ursprünglich genannt Entladen.

Die AppDomain entladen jetzt relativ schnell und mein Service stoppt ziemlich schnell.

+0

Wie hast du es gelöst? – Naha

+0

Dank dieser fünf Jahre alten Nachricht löste ich meine eigene Ausnahme, indem ich zwei Destruktorblöcke durch aufrufbare Aufräumroutinen ersetzte, so dass die nach dem Waschen entladene AppDomain damit endete, aber bevor die Objekte zerstört wurden. –

1

Versuchen Sie, alle AppDomains in einer einzigen Hintergrundaufgabe zu entladen statt einer Hintergrundaufgabe für jede AppDomain und verwenden ServiceBase.RequestAdditionalTime, so dass der SCM nicht Ihren Dienst nicht markiert nicht ansprechbar.

Verwandte Themen