.NET数据集处理 Foo1或Foo2?
请帮忙!我一直在寻找有关以下数据集处理问题的权威性权威性答案.我的客户坚持认为Foo1()中存在内存泄漏,因为未处理数据集.他希望任何功能返回 要改写为Foo2()的数据集,该数据集将适当地"处置该数据集. [示例代码如下].
我不同意.我相信以下是正确的. 如果我错了,请纠正我.请确认我是否正确.
问题
-  ; 将变量设置为Nothing后是否还有任何价值?大概这样做是为了帮助GC知道不再需要某个变量.
-  ; 在不同的.NET框架中,数据集处理是否会有所不同?仅供参考-该代码适用于ASP.NET 3.5 Framework 2.0网站.
-  ; 有没有办法通过简单的测试来证明这一点?
感谢您的回复.
------------------------示例代码--------------------- -----------
Sub Main()
暗 ds As 数据集
尝试
ds = Foo1( 从MyTable中选择内容" )
DisplayStuff(ds)
最后
如果应该完全丢弃数据集...则应在此处完成
一旦呼叫者完成操作后即可.
这里是否还需要布置? GC还是应该处理吗?
ds.Dispose()
ds = 没什么 是否有必要将此设置为空?
结束 尝试
结束 Sub
功能 Foo1(sql As 字符串 ) As 数据集
返回 GetDataSet(sql)
结束 功能
功能 Foo2(sql As 字符串 )
暗 ds As 数据集
尝试
ds = GetDataSet(sql)
返回 ds
最后
此代码是否必要?我们只是返回对数据集的引用.
ds.Dispose()
ds = 没有了
结束 尝试
结束 功能
功能 GetDataSet(sql As 字符串 )
暗 ds As 新 数据集
使用 db = 新 SqlConnection ( " SERVER = MyServer; DATABASE = MyDatabase;" )
db.Open()
使用 适应 As 新 SqlDataAdapter (sql,db)
Adapt.Fill(ds)
结束 使用
结束 使用
返回 ds
结束 功能
解决方案
您在所有方面都是正确的,您的客户端是错误的,部分原因是不得将数据集放在Foo2中(这样做将是一个错误),部分原因是未能处理数据集不会导致内存泄漏(因为DataSet类不执行任何操作) 调用Dispose时).
一旦将变量设置为Nothing,是否还有任何值?"
对于局部变量,这样做绝对没有任何价值. JIT编译器会知道何时不再使用该变量,并将其告知GC.
"在不同的.NET框架中,数据集处理是否会有所不同?仅供参考-该代码适用于ASP.NET 3.5 Framework 2.0网站."
不是,DataSet是可抛弃的事实只是不幸的结果,它源自MarshalByValueComponent类,仅此而已.
有没有办法通过简单的测试证明这一点?"
您可以将代码无限循环地放入Main方法中,并观察内存使用情况.或者,您可以使用探查器.
出于任何原因,无论是在互联网论坛上还是在Microsoft自己的文档中,我都找不到一个令人满意的答案."
您只是不处理/删除/销毁/完成/释放正在使用的对象,这是基本的.如果这样做,大多数对象将开始抛出ObjectDisposeException,但是它发生的原因是DataSet不在乎处理并且可以继续工作. 但这并不意味着使用像Foo2这样的代码是有效的.
.NET Dataset Disposal Foo1 or Foo2?
Please help! I have been searching for a definitive and authoritative answer on the dataset disposal issue below. My client insists that there is a memory leak in Foo1() since the dataset is not disposed. He would like any functions returning datasets to be rewritten as Foo2() which "properly" disposes of the dataset. [Sample code is below].
I disagree. I believe the following to be true. Please correct me if I am wrong. Please confirm if I am right.
Questions
- Is there still any value in setting the variable to Nothing once it is disposed? This is done presumably to aid the GC in knowing that a variable is no longer needed.
- Would there be any difference in the dataset disposal in difference .NET frameworks? FYI - This code is for a website ASP.NET 3.5 Framework 2.0.
- Is there any way to prove this with a simple test?
For whatever reason, I cannot find a satisfactory answer for all of this either on the internet forums or in Microsoft’s own documentation.
Thank you for your response.
------------------------ Sample Code --------------------------------
Sub Main()
Dim ds As DataSet
Try
ds = Foo1("select stuff from MyTable")
DisplayStuff(ds)
Finally
'If the dataset should be disposed at all...It should be done here
'once the caller is finished with it.
'Is disposing here even necessary? Shouldn’t the GC handle it anyway?
ds.Dispose()
ds = Nothing 'Is it necessary to set this to nothing?
End Try
End Sub
Function Foo1(sql As String) As DataSet
Return GetDataSet(sql)
End Function
Function Foo2(sql As String)
Dim ds As DataSet
Try
ds = GetDataSet(sql)
Return ds
Finally
'Is this code necessary? We're just returning a reference to a dataset.
ds.Dispose()
ds = Nothing
End Try
End Function
Function GetDataSet(sql As String)
Dim ds As New DataSet
Using db = New SqlConnection("SERVER=MyServer;DATABASE=MyDatabase;")
db.Open()
Using adapt As New SqlDataAdapter(sql, db)
adapt.Fill(ds)
End Using
End Using
Return ds
End Function
解决方案You're right on all points, your client is wrong partly because the data set must not be disposed in Foo2 (doing that would be a bug) and partly because failure to dispose a data set doesn't cause memory leaks (because the DataSet class doesn't do anything when Dispose is called).
"Is there still any value in setting the variable to Nothing once it is disposed?"
For local variables there's absolutely no value in doing this. The JIT compiler knows when the variable is no longer used and informs the GC about that.
"Would there be any difference in the dataset disposal in difference .NET frameworks? FYI - This code is for a website ASP.NET 3.5 Framework 2.0."
Nope, the fact that DataSet is disposable is just an unfortunate consequence of it deriving from the MarshalByValueComponent class, nothing more, nothing less.
"Is there any way to prove this with a simple test?"
You could put the code in the Main method in an infinite loop and observe the memory usage. Or you could use a profiler.
"For whatever reason, I cannot find a satisfactory answer for all of this either on the internet forums or in Microsoft’s own documentation."
You simply don't dispose/delete/destruct/finalize/release an object that's being used, that's elementary. Most objects will start throwing ObjectDisposeException if you do that but it happens so that DataSet doesn't care about disposal and continues to work. But that doesn't mean that using code like Foo2 is valid.
更多推荐
数据集发布...再次.
发布评论