2012-11-13 10 views
5

Otrzymuję ten błąd w usłudze Windows. Jest to ta sama usługa, że ​​wcześniej omówione w moim pytaniu hereBłąd podczas odciążania aplikacji. (Wyjątek od HRESULT: 0x80131015), wewnątrz usługi Windows

Kod jest zaktualizowany do korzystania Parallel.ForEach (własną wersję, ponieważ jest to usługa 3,5 windows). Powodem użycia Równoległego jest fakt, że rozładowanie każdej domeny trwało zbyt długo i równoległe działanie powinno być szybsze (wydaje się, że mimo tego, że istnieje tylko jeden wątek, który wykonuje każde Rozładowanie ?!).

podstawie innych stanowisk, mogę się tylko domyślać, że jest to w jakiś sposób się do tego używam ThreadPoolThread do Unload z AppDomain s. Po prostu nie rozumiem, jak tego uniknąć?

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

Czy próbowałeś dołączyć debugger do swojej usługi, aby zobaczyć dokładnie, kiedy to się dzieje w oknie wątków? Przy okazji, czy próbowałeś rozładować wszystkie domeny aplikacji w jednym zadaniu tła zamiast jednego zadania tła dla każdego elementu AppDomain? –

+0

@PanosRontogiannis problem polegał na tym, że gdy uruchomiłem go w jednym wątku, po prostu trwało zbyt długo, aby 'OnStop' mógł zostać wydany. Nadal badam z pewnymi podejrzeniami co do problemu. –

Odpowiedz

6

Wyśledziłem to jako błąd jednego z AppDomain s przy wyjściu czekając na WaitHandle, która nigdy nie została ustawiona.

Jeśli nić nie przerwać, na przykład dlatego, że jest wykonywany kod niezarządzany, albo dlatego, że jest wykonywany bloku finally, a następnie po okres czasie CannotUnloadAppDomainException zostaje rzucony w wątku że pierwotnie zwany Rozładować.

Teraz rozładowuje się stosunkowo szybko i moja usługa zatrzymuje się dość szybko.

+0

Jak to rozwiązałeś? – Naha

+0

Dzięki temu pięcioletniemu komunikatowi rozwiązałem swój wyjątek, zastępując dwa bloki destruktora za pomocą rutynowych procedur czyszczenia, tak aby AppDomain był rozładowywany po tym, jak skończyłem, ale zanim obiekty zostały zniszczone. –

1

Spróbuj rozładować wszystkie AppDomains w jednym zadaniu tle zamiast jednego zadania tła dla każdego AppDomain i używać ServiceBase.RequestAdditionalTime tak, że SCM nie oznaczyć swoje usługi jako nie reaguje.

Powiązane problemy