电脑故障

位置:IT落伍者 >> 电脑故障 >> 浏览文章

DataTable.NewRow 内存洩漏问题


发布日期:2019/10/11
 

先看一下有问题的代码

public DataRow GetNextRow()

{

if (_DataReaderRead())

{

DataRow row = _SchemaTableNewRow();

foreach (DataColumn col in _SchemaTableColumns)

{

row[colColumnName] = _DataReader[colColumnName];

}

return row;

} else { return null;

}

}

这段代码我希望通过SqlDataReader 对象 _DataReader 来获取一行数据_SchemaTable 是一个DataTable 对象这个DataTable对象没有记录只存放Table 的Schema乍一看好像没有什么问题_SchemaTableNewRow() 是根据_SchemaTable 的列信息生成一个新行但这个新行并没有调用 _SchemaTableRowsAdd 方法加入到_SchemaTable 表中一般认为这个新生成的 DataRow 在使用完后会被自动回收但实际情况并不是这样只要_SchemaTable 不释放_SchemaTableNewRow 生成的所有DataRow都无法释放

网上搜了一下有一位仁兄和我遇到同样问题 Table NewRow() Causes Memory Leak

被采纳的解决意见是这样的

DataTableNewRow() adds the created row to the DataTables RecordManager

I am not entirely sure why this happens but this is why it is not freed by the GC

It appears that there are only two ways to get rid of the DataRow:

Add it to the table then delete it

Call DataTableClear()

也就是说DataTableNewRow 方法创建的DataRow 对象会被加入到DataTable 的 RecordManager 中我们可以通过以下两种方法来释放掉它

通过 DataTableRowsAdd 方法将这一行加入到DataTable 中然后再通过 DataTableRowsRemove 方法删除它

调用 DataTableClear() 方法释放

由于我这个应用中数据表只存放架构信息始终是空表所有我采用了第种方法加入 _SchemaTableClear() 这一句后内存洩漏问题解决

改正后的代码如下

public DataRow GetNextRow()

{

if (_DataReaderRead())

{ DataRow row = _SchemaTableNewRow(); foreach (DataColumn col in _SchemaTableColumns)

{

row[colColumnName] = _DataReader[colColumnName];

}

_SchemaTableClear(); return row;

}

else

{

return null;

}

}

不好意思上面代码还是有问题 _SchemaTableClear() 后DataRow 里面的数据都会被清空必须在调用完新生成的DataRow后再 _SchemaTableClear 才行特此更正

上一篇:老生常谈:策略模式

下一篇:下拉框层级绑定