数据集发布...再次. [英] Dataset Dispoal...again.

查看:120
本文介绍了数据集发布...再次.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET数据集处理

Foo1或Foo2?

请帮忙!我一直在寻找有关以下数据集处理问题的权威性权威性答案.我的客户坚持认为Foo1()中存在内存泄漏,因为未处理数据集.他希望任何功能返回 要改写为Foo2()的数据集,该数据集将适当地"处置该数据集. [示例代码如下].

我不同意.我相信以下是正确的.  如果我错了,请纠正我.请确认我是否正确.

  1.       是否完全没有必要在 intermediate 函数(例如Foo())中处理数据集,该函数仅获取对数据集的引用并将该引用返回给调用方.
  2.       您可以辩称,您不必丢弃数据集.

    1.       GC将自动处理此问题.
    2.      数据集处置仅是MarshalByValueComponent继承的副产品. -由于数据集不包含任何非托管资源,因此处理不会做任何事情.
    3.       counter参数是对实现它的任何类都应调用dispose.即使数据集处理现在什么也不做,Microsoft保留将来更改它的权利.
    4.      不仅不需要在中间函数中处理数据集-这很危险.假设配置实际上清除了内存?有将一无所有!数据将被清除.这实际上是 如果这是一个数据视图的话.

  3.       如果根本不应该要求处置,这是呼叫者的责任.根函数在使用完数据集后应立即将其丢弃.无需通过任何数量的中间对象来继续处理返回的数据集 呼叫.

问题

-     ;     将变量设置为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 数据集

         返回     结束 功能

    功能 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 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.

  1.        Is it completely unnecessary to dispose of a dataset in an intermediate function (such as Foo()) which merely gets a reference to a dataset and returns that reference to the caller. 
  2.        You can argue that you never have to dispose of the dataset. 

    1.        The GC will handle this automatically.
    2.       The dataset dispose is only there as a byproduct of inheritance from MarshalByValueComponent  - since a dataset contains no unmanaged resources dispose doesn’t do anything anyway.
    3.        The counter argument is that dispose should be called for any class that implements it. Even though dataset dispose does nothing now Microsoft reserves the right to change that in the future.
    4.       Not only is disposing of the dataset in the intermediate function unnecessary – It is dangerous.  Suppose dispose actually did clear the memory? There  would be nothing to return!  The data would be wiped out.  This is actually the case if this were a dataview instead.

  3.        If dispose should be called at all, it is the caller’s responsibility.  The root function should dispose of the dataset once it is finished using it.  There is no need to keep disposing of returned datasets through any number of intermediate calls.

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.


这篇关于数据集发布...再次.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆