7

マルチスレッドアプリケーションがあり、aCancellationTokenは共有オブジェクトとして使用されています。すべてのスレッドがトリガーして、他のスレッドにジョブがキャンセルされたことを通知できます。次に、1つのスレッドがクリーンアップを実行し、このようにすべてのオブジェクトを破棄しますCancellationToken。次に、スレッドがそれを使用しようとすると、例外が発生します。

CancellationTokenSourceは破棄されました。

オブジェクトを使用する前に、オブジェクトが廃棄されていることを確認するにはどうすればよいですか?

4

4 に答える 4

4

さて、Reflectorによると、あなたに伝えることができCancellationTokenSourceた内部IsDisposedメソッドがありますが、それは内部であるため、あなたはそれを呼び出すことになっていない。

いずれにせよ、あるスレッドが他のスレッドが依存しているデータ構造とオブジェクトをヤンクアウトする場合は、そうしないでください。コードを修正し、それらのオブジェクトを必要な間存続させます。

つまり、他のスレッドが必要になるのを待ってから破棄しCancellationTokenSourceます。

于 2011-04-13T20:47:05.493 に答える
3

適切なアクションのコースは、一部の使い捨てオブジェクトの作成者が、破棄されたオブジェクトに対してアクションを実行すると例外がスローされるというMicrosoftの「ルール」にわずかに反し、代わりに、いつでも例外がスローされるというより一般的なルールに従うことです。メソッドの事後条件を満たせません。Cancelメソッドの目的が、ジョブがライブであると誰も見なさないようにすることであり、Cancelメソッドが呼び出される前であっても、全員がジョブを停止していると見なす場合、メソッドの事後条件は、オブジェクトが破棄されるかどうか。

一般に、適切に設計されたオブジェクトの外部にあるコードは、破棄されたことを表明する場合を除いて、破棄されたかどうかを照会する必要はありません。代わりに、オブジェクト自体が、破棄されたオブジェクトでの意味が明確で明確なメソッドを提供する必要があります。これらのメソッドは内部でIsDisposedフラグを使用する場合がありますが、競合状態を防ぐために必要なロックを使用する必要があります。一般的に、パターン

  if(!myThing.isDisposed)
    myThing.DoSomething();

myThingが実際にDoSomethingIfNotDisposedメソッド(おそらくTryDoSomethingと呼ばれる)をサポートする必要があることを示しています。それができない場合は、独自のDoSomethingIfNotDisposed拡張メソッドを作成し、Try / Catchを使用してObjectDisposedException(またはオブジェクトがスローする特定の例外)を抑制します。

于 2011-04-14T15:50:47.677 に答える
1

使用する前に、オブジェクトが廃棄されているかどうかを確認してください。

まだ最高のデザインパターンではありません。ただし、これが私が使用するもので、オブジェクトが廃棄されているかどうかを判断します。

if (!object.IsDisposed) object.DoSomething();

また

public string DoSomething()
{
    if (this.IsDisposed) return null;
}

それが機能しない場合は、IsDisposedフラグを追加し、disposeメソッドをオーバーライドしてみてください。そして、それをあなた自身のコードでtrueに設定します。

于 2011-04-13T20:49:02.913 に答える
1

クラスを継承し、プロパティを追加します。

class MyCancellationTokenSource: CancellationTokenSource
{
    public bool MyIsDisposed { get; private set; }
    protected override void Dispose(bool disposing)
    {
        base.Dispose(disposing);
        MyIsDisposed = true;
     }
}
于 2017-11-02T13:43:10.207 に答える