2012-11-13 63 views
5

內我收到一個窗口服務這個錯誤。 這是我在我的問題here卸載appdomain時出錯。 (從HRESULT異常:0x80131015),Windows服務

前面討論的相同服務的代碼修改爲使用Parallel.ForEach(我自己的版本,因爲這是一個3.5窗口服務)。究其原因,並行使用減少了一個事實,即它只是時間太長,卸載每個域和並行運行它們應該被證明是更快的(似乎是即使只有一個,就是在做每個卸載?線程)。

基於其他職位,我只能猜測,這是莫名其妙地倒在其實我使用的是ThreadPoolThreadUnloadAppDomain秒。我只是看不到如何避免它?

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

您是否嘗試過一個調試器附加到您的服務,看什麼時候該使用線程窗口發生了什麼?順便說一下,您是否試圖在一個後臺任務中卸載所有AppDomain,而不是每個AppDomain的後臺任務? –

+0

@PanosRontogiannis當我跑它在一個單一的後臺線程它的問題只是時間太長了'OnStop'到exeute。仍在調查有關這個問題的一些懷疑。 –

回答

6

我就找到了這個bug的AppDomain S於出口等待那個從來沒有設置的WaitHandle之一。

如果一個線程不會中止,例如,因爲它正在執行 非託管代碼,或者是因爲它在執行finally塊,然後 經過一段時間的CannotUnloadAppDomainException在 線程拋出原來調用卸下。

AppDomain現在卸載相對較快,我的服務很快就會停止。

+0

你是如何解決它的? – Naha

+0

由於這個五歲的消息,我用可調用清理程序取代兩顆析塊解決我自己的異常,讓我洗它結束後,但被破壞的對象之前卸載的AppDomain。 –

1

嘗試卸載所有應用程序域在一個後臺任務,而不是一個後臺任務爲每個應用程序域,並使用ServiceBase.RequestAdditionalTime,以便SCM並不標誌着你的服務不響應。

相關問題