10

DataContract以下を実装するものを定義しましたIDisposable

[DataContract]
public class RegularFileMetadata : FileMetadataBase, IDisposable
{
   bool _Disposed = false; //note this!

   //...

   protected virtual void Dispose(bool disposing)
   {
      if (!_Disposed)
      {
          //...
          _Disposed = true; //note this too!
      }
   }
   public void Dispose()
   {
      Dispose(true);
      GC.SuppressFinalize(this);
   }
}

そして、上記のデータ コントラクトのインスタンスを渡す次のサービス メソッドを呼び出します。

[OperationContract]
[ServiceKnownType(typeof(RegularFileMetadata))]
Guid BeginUpload(FileMetadataBase metadata);

の実装では、メタデータを次のようにディクショナリにBeginUpload保存するだけです。

Dictionary<Guid, RegularFileMetadata> _Dict;

public Guid BeginUpload(FileMetadataBase fileMetadata)
{
    //...
    var metadata = fileMetadata as RegularFileMetadata; 
    Guid sessionId = Guid.NewGuid();
    _Dict.Add(sessionId, metadata); //metadata SAVED!
    return sessionId ;
}

私の質問は、このメソッドから戻った直後にDispose()、インスタンスをディクショナリに保存したにもかかわらず、なぜ呼び出されるの_Dictですか?

メソッドが辞書に保存したのと同じDispose()インスタンスで呼び出されることを確認しました。保存されたオブジェクトのようになります。_Disposedtrue_Dict[sessionId]._Disposedtrue

私のサービスのサービス動作は次のように設定されています。

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
4

1 に答える 1

15

そのオブジェクトは WCF に「属している」ため、破棄されています。メソッドにパラメーターとして渡すために、何もないところからオブジェクト インスタンスを作成しました。そして、このオブジェクトが を実装していることを観察するのに十分親切であるIDisposableため、メソッドが完了すると破棄されます。

メソッドの完了後にこのオブジェクトのインスタンスを保持したい場合は、そのようなインスタンスを自分で作成し、関連する詳細を 1 つのインスタンスから別のインスタンスにコピーする必要があります。

Dispose()インスタンスを辞書に保存したにもかかわらず、なぜ呼び出されるのか_Dict

Disposeパターンは参照やガベージ コレクションとは関係がないためです。重要なのは、使い捨てオブジェクトへの参照が複数のメソッド/アクター/エージェント間で渡されるときはいつでも、「誰が」いつ呼び出しを担当するかについて合意があるということですDispose。この例では、「誰」が WCF インフラストラクチャです。


OperationBehavior修正 -メソッドに属性を追加し、 AutoDisposeParametersfalse に設定することで、この動作を変更できます。

[OperationBehavior(AutoDisposeParameters=false)]
public Guid BeginUpload(FileMetadataBase fileMetadata)
{
    //...
    var metadata = 
于 2012-07-09T08:07:43.103 に答える