1

Dispose メソッド内から Dispose をキャンセルできる方法はありますか。つまり、A.Dispose() が呼び出されたときに A を破棄しないでください。

更新 うまく説明できませんでした。私が持っているのは、別のスレッドで実行されるポップアップ ウィンドウにプログレス バー (マーキー) を表示するクラスです。プログレス ポップアップが作成されると、コントローラーのような使い捨てオブジェクトが返されるため、次のようなことができます。

using (var progress = Dialogs.ShowProgress("Please wait..."))
{
    // do lots of stuff here
    progress.UpdateStatus("Please wait some more...");
    // do more stuff
}

using ブロックが終了すると、進行状況ウィンドウが閉じられ、破棄されます。

現在、このブロック内で発生することが進行状況ウィンドウも作成する状況があり、新しいオブジェクトを返して新しいウィンドウを作成する代わりに、最初のインスタンスによって作成されたオブジェクトを返し、最初のインスタンスが破棄されたときにのみ破棄したかった.

更新Dialogs.ShowProgress()OK、私がしたことは、呼び出し ごとに新しい IDisposable オブジェクトを作成し、元のコントローラー オブジェクトをそれにアタッチすることでした。これらのオブジェクトは、処理が完了するたびに破棄されます。コントローラーは、破棄するオブジェクトが残っている場合にのみ破棄されます。

4

5 に答える 5

4

IDisposable他の人が言ったように、実際には処分しないかもしれない方法で実装するのは悪い考えです。やろうとしていることを実装する別の方法を次に示します。

interface IMaybeDisposable
{
    bool TryDispose(); //return false if dispose was canceled
}

次のように使用できます。

IMaybeDisposable maybe = //something
try
{
    // do something with maybe
}
finally
{
    if (maybe.TryDispose())
        // yay, it disposed!
    else
        // hm, it didn't dispose; do something else
}
于 2013-03-20T19:33:28.230 に答える
1

私はこれをすることに注意するでしょう。usingブロックの最後でメソッドの破棄をキャンセルすると、そのオブジェクトへの参照が失われ、そのコンテンツを再度破棄する機会がなくなります。つまり、次の場合にリソースがリークする可能性があります。注意しないでください。特に、disposeメソッドが、何らかの理由でガベージコレクションをすぐに実行したくない大きなオブジェクトへの参照を解放した場合にのみ、これを自分で行います。ファイル、データベース接続、ネットワークソケット、またはガベージコレクションできないその他のものへのハンドルの解放をスキップするためにこれを行うことはありません。

コメント提供者が指摘したように、破棄をキャンセルして解決しようとした問題が他の危険性の低い方法で解決されるように、コードをリファクタリングしようとしました。

何かを破棄することをスキップする必要があるエッジ状態があると絶対に確信している場合は、次の方法があります。

public void Dispose()
{
     if(condition)
     {
         // do disposing stuff
     }
}
于 2013-03-20T19:25:06.297 に答える
1

に必要な事後条件Disposeは、必要なクリーンアップが未完了になることなく、クライアント コードがオブジェクトへのすべての参照を破棄できることです。Disposeが呼び出される前にその条件が適用される場合、Disposeメソッドは正当に何もしない可能性があります。その条件が当てはまらない場合は、そうさDisposeせなければならず、そうしない限り、またはそうするまで正当に返されない可能性があります[Dispose実際にクリーンアップを実行する必要はないことに注意してください。後で]。インターフェイスのコントラクトには、Dispose他の手段でクリーンアップが行われると信じる理由がない限り、オブジェクトをさらにクリーンアップする必要がある状態のままにすることは許可されていません。

于 2013-03-20T19:40:19.670 に答える
1

もちろん。オブジェクトを破棄するために行ったことは何でもしないでください。特別なことを積極的に行う必要はありません。

ただし注意してください。誰かがオブジェクトを処分するとき、とにかくあなたを無視して保持するのではなく、実際に管理されていないリソースを処分することを期待しています。

于 2013-03-20T19:23:14.600 に答える
0

あなたの更新に基づいて、私は次のようなことをします:

 public  void  DoStuff()
{
     DoPrepWork();
     using( var  controller =  TheMethodYouWroteThatShouldReturnAController())
    {
         DoStuffOverControllerLifetime();
    }
}
于 2013-03-20T19:54:33.827 に答える