6

Windowsサービスでこのエラーが発生します。これは、ここでの質問で以前に説明したのと同じサービスです。

コードは使用するように改訂されていますParallel.ForEach(これは3.5 Windowsサービスであるため、私自身のバージョンです)。並列使用の理由は、各ドメインのアンロードに時間がかかりすぎて、それらを並列で実行する方が高速であることが証明されるはずであるという事実にあります(各アンロードを実行しているスレッドが1つしかない場合でもそうです?!)。

他の投稿に基づいて、私はこれがどういうわけか私がsにaを使用しているという事実に帰着していると推測することができThreadPool Threadます。私はそれを避ける方法がわかりませんか?UnloadAppDomain

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);
    }
}
4

2 に答える 2

6

AppDomain設定されていないWaitHandleを待機している出口の1つに対するバグとして、これを追跡しました。

アンマネージコードを実行している、またはfinallyブロックを実行しているなどの理由でスレッドが異常終了しない場合、一定期間後、Unloadを最初に呼び出したスレッドでCannotUnloadAppDomainExceptionがスローされます。

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

于 2012-11-15T13:04:06.653 に答える
1

AppDomainごとに1つのバックグラウンドタスクではなく、単一のバックグラウンドタスクですべてのAppDomainをアンロードし、ServiceBase.RequestAdditionalTimeを使用して、SCMがサービスを応答しないとマークしないようにします。

于 2012-11-15T12:59:23.767 に答える