2012-11-13 103 views
5

Windowsサービスでこのエラーが発生します。 これはhereappdomainをアンロード中にエラーが発生しました。 (HRESULTからの例外:0x80131015)、Windowsサービス内

コードは(これは3.5のWindowsサービスであるように私自身のバージョン)Parallel.ForEachを使用するように改訂され、私は以前に私の質問で説明したのと同じサービスです。 Parallelを使用する理由は、各ドメインをアンロードするのに時間がかかり過ぎるため、パラレルで実行するほうが速くなるはずです(各Unloadを実行するスレッドが1つしかないように見えます)。

他の記事に基づいて、私はこれだけがダウンして、私はThreadPoolThreadUnloadAppDomain Sを使用しています実際に何らかの形であることを推測することができます。私はそれを避ける方法を見ることができません?

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ごとに1つのバックグラウンドタスクではなく、1つのバックグラウンドタスクですべてのAppDomainsをアンロードしようとしましたか? –

+0

@PanosRontogiannis問題は、単一のバックグラウンドスレッドで実行したときに 'OnStop'が実行するのに時間がかかりすぎたという問題でした。問題について何らかの疑念を持って調査中。 –

答えて

6

これは決して設定されていないWaitHandleを待つ出口でAppDomainのいずれかのバグとしてこれを追跡しました。

それは アンマネージコードを実行されるため、またはそれが最終的にブロックを実行しているため、その後、 までの時間がCannotUnloadAppDomainExceptionが最初に呼び出され スレッドでスローされたスレッドには、例えば、中断していない場合アンロードします。

AppDomainは、比較的迅速にアンロードされ、サービスは非常に迅速に停止します。

+0

どうやって解決しましたか? – Naha

+0

この5年前のメッセージのおかげで、2つのデストラクタブロックを呼び出し可能なクリーンアップルーチンに置き換えることで、自分自身の例外を解決しました。そのため、AppDomainは、洗濯後にアンロードされました。 –

1

それぞれのAppDomainのための代わりに1つのバックグラウンドタスクの単一のバックグラウンドタスク内のすべてのAppDomainをアンロードし、SCMが応答としてあなたのサービスではなくマークしないようにServiceBase.RequestAdditionalTimeを使用してみてください。

関連する問題