6

Threadクラスを使用するクラスがあります。

class A
{
    public Thread thread
    { get; set; }
}

IDisposable を実装し、Thread プロパティを null に設定する必要がありますか?

class A : IDisposable
{
    public Thread Thread
    { get; set; }

    protected bool Disposed
    { get; set; }


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

    protected virtual void Dispose(bool disposing)
    {
        if (!this.Disposed)
        {
            if (disposing)
            {
                if (Thread != null)
                    Thread = null;
            }

            Disposed = true;
        }
    }
}

か否か?
なんで?

4

2 に答える 2

8

IDisposableクラスがアンマネージ オブジェクト、リソース、またはその他のオブジェクトを処理する場合にのみ実装しIDisposableます。Thread はアンマネージ オブジェクトではなく、何も参照されていない場合、またはスレッドを処理しているプロセスが終了した場合に、ガベージ コレクションが行われます。Thread は を実装IDisposableしていないため、それを参照するクラスもそれを実装する必要はありません。

オプションでIDisposable、メソッドのスコープ内では、それらをステートメントでラップすることができusing、スコープから出ると Dispose() メソッドが自動的に呼び出されます。

于 2012-10-29T15:04:17.110 に答える
2

スレッドが何をしているかによって異なります。スレッドが無期限に実行される可能性のある長時間実行されるタスクを実行している場合、そのスレッドをリソース (ガベージ コレクションされない) と見なします。たとえば、スレッドが特定の状態を無期限にポーリングするように設計されているか、キューからアイテムを消費するように設計されているか (スレッドプール スレッドがタスクを消費したり、TCP サーバーが新しい接続を消費したりするように) などを考えてみてください。クラスを破棄すると、このスレッド リソースが解放されます。この場合、null に設定してもあまり役に立ちません。それよりもDisposeおそらく、同期イベント (またはおそらく CancellationToken) にフラグを立てて、無限タスクを終了する必要があることをスレッドに通知する必要があります。その後、スレッドを破棄するスレッドは、スレッドが終了 (結合) するまでしばらく待機する必要があります。結合の場合と同様に、デッドロック シナリオに注意し、スレッドが終了を拒否した場合は代替アクションを検討してください。明らかな理由から、ファイナライザーでこの結合を行いません。

class A私が言っていることの例として、あなたが実際class MyTcpListenerに、特定のポートで新しい TCP 接続をリッスンして無期限に待機するように設計されているシナリオを考えてみましょう。次に、次の (あまりありそうにない) コードで何を期待するかを考えてみましょう。

using (MyTcpListener listener = new MyTcpListener(port:1234))
{
    // Do something here
}

// Create another one. This would fail if the previous Dispose
// did not unbind from the port.
using (MyTcpListener listener = new MyTcpListener(port:1234))
{
    // Do something else here
}

MyTcpListenerのコンストラクターがリスナースレッドを作成することを知っていると仮定すると、Dispose呼び出しが返された後MyTcpListener、TCPポートにバインドされなくなる、つまりTCPリスナースレッドが完全に終了することが予想されます。言うまでもなく、リスナーを停止するメカニズムを提供しなければ、リソース リークが発生します。停止メカニズムは「Stop」メソッドの呼び出しである可能性がありますが、個人的には、「Dispose」パターンがこのシナリオにより適していると思います。何かを停止するのを忘れても、通常はリソース リークを意味するわけではないからです。

あなたのコードは異なる仮定を必要とするかもしれないので、シナリオで判断することをお勧めします。スレッドが短時間しか実行されない場合、たとえば、完了すべき既知の有限タスクがあり、その後自然に終了する場合、破棄はそれほど重要ではないか、おそらく役に立たないと言えます。

于 2012-10-29T15:54:12.693 に答える