1

在 RX Framework 中使用类时,我们如何释放类中的资源?我在 C# 4.0 lib 项目中有一个类,其中包含 Web 服务代理、ado.net 对象等,我也实现了 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

据我所知,您发布的 Rx 中没有任何内容本身会出现内存泄漏。正如其他人所指出的那样,您是在查询完成之前处理您的类 - 如果没有看到更多代码,很难说出可能导致什么问题。

但是,您显然有泄漏。当遇到此类问题时,我建议在您的代码上运行内存分析器。这是深入了解它的最快方法。

如果您没有足够高的 Visual Studio 版本,则可以下载 Visual Studio 的试用版或任意数量的商业产品。我强烈推荐SciTech 的分析器,因为它非常易于使用并且有很好的教程。

于 2013-10-28T21:33:09.600 回答
0

我不确定你那里没有太多代码。据我所知,当您认为它会调用时,不会调用您的 Disposable clean up 。假设 MyClass 填充 LongRunMethods 中的 DataTables,那么您实际上永远不会清理。

您的 Dispose 在 MyClass 实例化后立即调用,并且很可能在 LongRunMethods 开始之前调用!

尝试将上面的替换为...

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 回答