Reactive中使用的类内存不足异常

本文关键字:内存不足 异常 Reactive | 更新日期: 2023-09-27 18:00:11

当类在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方法,一旦它完成,就会释放所有资源。然而,为什么内存不足是个例外。

这里出了什么问题。

Reactive中使用的类内存不足异常

我不确定,因为那里没有太多代码。从我所看到的是,当你认为会调用一次性清理时,它并没有被调用。假设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。

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

然而,你显然有漏洞。当遇到这种问题时,我建议对代码运行内存探查器。这是找到真相的最快方法

如果您没有足够高的Visual Studio版本,那么您可以下载Visual Studio的试用版或任何数量的商业产品。我强烈推荐SciTech的探查器,因为它非常容易使用,并且有一个非常好的教程。