1

RX フレームワークでクラスを使用する場合、クラス内のリソースを解放するにはどうすればよいですか? Web サービス プロキシ、ado.net オブジェクトなどを含む C# 4.0 lib プロジェクトのクラスがあり、IDisposable も実装しました。このクラスには実行中のメソッドがあり、このメソッド内でデータをデータセットに保存しています。最終的にメソッドが終了したら、データセットを DB に保存します。

Dispose メソッドで、データセットを null に設定し、他の Web サービス プロキシ オブジェクトを null に設定しています。ただし、このクラスがリアクティブ拡張メソッドで頻繁に使用されると、メモリ例外がスローされます。

public class MyClass : IDisposable
 {
     proxy object;
     DataSet object; // This dataset has 2 tables with relation set each other

     public string LongRunMethods(string code)
     {
        // iterrating a for loop...
        // insert new row into the 1st table of dataset in each loop
        // another loop
        // insert new row into the 2nd table of dataset in each loop
        // Bulk save the dataset to Database
        // return string;
      }

      private void Dispose()
      {
         // nulling all the objects...[proxies, datasets, etc

      }
  }

そして、このクラスは以下のように1000回作成して使用しています。

   IObservable<string> RunProcess(Employee emp)
    {           
       using (MyClass p = new MyClass ())
        {
          return Observable.Start(() => p.LongRunMethods(emp.Code), scheduler.ThreadPool);
        }                        
    }

この EmployeeDatas は、1000 個の従業員オブジェクトのリストです。

  EmployeeDatas.ToObservable().Select(x => RunProcess(x).Select(y => new { edata = x, retval = y }))
                .Merge(10)
                .ObserveOn(Scheduler.CurrentThread)
                .Subscribe(x =>
                {
                    SendReportStatus(x.retval.Item1, x.retval);                           
                });

すべてが正常に機能しています。しかし、300 番目以降の従業員オブジェクトを処理すると、MyClass でメモリ不足の例外がスローされることがあります。

MyClass で dispose メソッドを使用しています。これは、終了したらすべてのリソースを解放します。それでも、なぜメモリ不足の例外が発生するのですか。

ここで何が問題なのですか。

4

2 に答える 2

0

あなたがそこに多くのコードを持っていないことを考えると、私は確信が持てません。私が見ることができるのは、使い捨てのクリーンアップが呼び出されると思ったときに呼び出されないということです。MyClass が LongRunMethods の DataTables にデータを入力すると仮定すると、実際にはクリーンアップすることはありません。

MyClass がインスタンス化された後、おそらく LongRunMethods が開始される前に Dispose が即座に呼び出されます。

上記を次のように置き換えてみてください...

IObservable<string> RunProcess(Employee emp)
{  
   return Observable.Using(() => new MyClass(), p => p.LongRunMethods(emp.Code), scheduler.ThreadPool);
}

これにより、OnCompleted() を呼び出した後に MyClass が破棄されます。

于 2013-02-25T09:14:59.400 に答える