1

以下に示すように、サードパーティのアセンブリを使用してプロジェクトに sftp 機能を提供しています。複数のスレッドがこの機能を実装する必要があるため、サードパーティのアセンブリは静的ヘルパー クラスで使用されます。

sftp サーバーは存在するが、ファイルを配置しようとしているディレクトリが削除されるなど、異常なエラー状態が発生しない限り、サード パーティのアセンブリは正常に機能します。これが発生すると、有効な例外がスローされますが、クライアントの新しいインスタンスが機能しないため、断続的に 3 番目のパーツ アセンブリが正しくクリーンアップされていないように見えます。

static readonly object _locker = new object();

    static void WorkerMethodCalledByThread()
    {
        lock(_locker)
        {
            var client = new ThirdPartyAssembly();
            bool hasConnection = false;
            try
            {
                client.Connect("some connection details");
                hasConnection = true;
                // do some work - 
                //but if an issue happens here then no new instances of ThirdPartAssembly work
            }
            catch(Exception e)
            {
                Logger.LogError(e);
            }
            finally
            {
                if (hasConnection) { client.Close(); }
            }
        }
    }

サードパーティのアセンブリを変更する手段がないため、探しているのは、使用した可能性のあるリソースを処分する方法です。ただし、呼び出されるサードパーティ クラスは IDisposable 自体を実装していません。

だから..サードパーティが使用するリソースを解放できるかどうかを調べようとしていますか?

私が考えることができる2つの可能なアプローチは次のいずれかです

1: サードパーティ クラスを基本クラスとして持ち、IDisposable も実装するラッパー クラスを追加します (以下を参照) - ただし、これで基本クラスがクリーンアップされないことは確かです

2: サードパーティ クラスへの WeakReference を使用します (以下を参照)。ただし、これが機能するかどうかはわかりません。

ラッパー クラス

public class WrapperClass : ThirdPartyClass, IDisposable
{
    ~WrapperClass()
    {
        Dispose();
    }

    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

弱参照

static readonly object _locker = new object();

    static void WorkerMethodCalledByThread()
    {
        lock(_locker)
        {
            var client = new WeakReference(new ThirdPartyAssembly());
            bool hasConnection = false;
            try
            {
                ((ThirdPartyAssembly)client.Target).Connect("some connection details");
                hasConnection = true;
                // do some work - 
                //but if an issue happens here then no new instances of ThirdPartAssembly work
            }
            catch(Exception e)
            {
                Logger.LogError(e);
            }
            finally
            {
                if (hasConnection) { ((ThirdPartyAssembly)client.Target).Close(); }
            }
        }
    }
4

1 に答える 1

1

したがって、の問題WeakReferenceは次のとおりです。

そのオブジェクトをガベージ コレクションによって再利用できるようにします

GC が内部で適切に管理されていないことは明らかであるため、GC がそれに到達することを保証するものではありません。

より良いアプローチは、クラスをベースにして実装することIDisposableです。usingこれにより、ステートメントでラッパーを活用できます。ただし、警告はこれであり、これを回避する方法は実際にはありません。使用Reflectionして、このクラスを掘り下げてクリーンアップする必要があります。

多くのブレークポイントが必要で、Watchウィンドウを掘り下げる必要がありますが、やり遂げることができます。

于 2013-08-02T13:25:29.747 に答える