.NET销毁对象的一个问题

楚狂歌 2014-10-24 01:44:03
写了一个类cls,其中有Private mOleDbConnection As New OleDb.OleDbConnection

做了一个mOleDbConnection.open动作

然后我想在Finalize()中销毁mOleDbConnection,于是有

Protected Overrides Sub Finalize()
If Not mOleDbConnection Is Nothing Then
mOleDbConnection.Dispose()
End If
MyBase.Finalize()
End Sub

但是我每次执行的类cls=nothing时报错,“System.InvalidOperationException”类型的未经处理的异常在 System.Data.dll 中发生

其他信息: 句柄未初始化。

VB6每次set nothing都会执行 Class_Terminate,而VB.net不会立即执行清理

那么我要怎么才能立即销毁类里面的这个模块级的mOleDbConnection?
...全文
305 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
楚狂歌 2014-10-28
  • 打赏
  • 举报
回复
还是每次打开连接用完然后就销毁好了,set nothing时关闭连接简直丧心病狂 VB6的Terminate多好。。。 谢谢Tiger_Zhao的回答
Tiger_Zhao 2014-10-28
  • 打赏
  • 举报
回复
state、Connectionstring 都属于内部资源,所以 Finalize 时可以访问。
而连接的关闭需要操作外部资源,调用出错有什么好奇怪的!
楚狂歌 2014-10-28
  • 打赏
  • 举报
回复
引用 12 楼 Tiger_Zhao 的回复:
[Quote=MSDN:]对象生存期:如何创建和销毁对象
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
    If Not Me.disposed Then
        If disposing Then
            ' Insert code to free unmanaged resources.
        End If
        ' Insert code to free shared resources.
    End If
    Me.disposed = True
End Sub
 
Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub
 
Protected Overrides Sub Finalize()
    Dispose(False)
    MyBase.Finalize()
End Sub
[/Quote] 按照上面的模板,外部资源应该在 Finalize() 之前显式调用 Dispose() 释放的。 也就是 Finalize() 的时候已经不能正常操作 Connection 了。
又调试了下, MyBase.Finalize()之前的Connection操作都很正常,Connection.state,Connection.Connectionstring都可以取得,就是不能dispose和close 如果不打开连接,则Protected Overrides Sub Finalize()中的调用dispose不会出错
Tiger_Zhao 2014-10-28
  • 打赏
  • 举报
回复
[Quote=MSDN:]对象生存期:如何创建和销毁对象
这两个垃圾回收系统之间的另一个差异涉及到 Nothing 的使用。为利用 Visual Basic 6.0 和早期版本中的引用计数,程序员有时将 Nothing 赋给对象变量以释放这些变量所保存的引用。如果变量保存的是对对象的最后一个引用,对象的资源将立即被释放。在 Visual Basic 的更高版本中,尽管可能存在此过程仍然有价值的情况,但执行此赋值操作从不会导致被引用对象立即释放其资源。若要立即释放资源,请使用对象的 Dispose 方法(如果可用)。只有当变量生存期相对于垃圾回收器检测孤立对象所需时间较长时,才应当将变量设置为 Nothing。[/Quote]
所以现在的机制 Set Nothing 不会关连接,要关连接必须显式调用 Dispose 或类似的 Close 方法。
Tiger_Zhao 2014-10-28
  • 打赏
  • 举报
回复
[Quote=MSDN:]对象生存期:如何创建和销毁对象
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposed Then
If disposing Then
' Insert code to free unmanaged resources.
End If
' Insert code to free shared resources.
End If
Me.disposed = True
End Sub

Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub

Protected Overrides Sub Finalize()
Dispose(False)
MyBase.Finalize()
End Sub
[/Quote]
按照上面的模板,外部资源应该在 Finalize() 之前显式调用 Dispose() 释放的。
也就是 Finalize() 的时候已经不能正常操作 Connection 了。
楚狂歌 2014-10-28
  • 打赏
  • 举报
回复
引用 10 楼 u011266608 的回复:

 Protected Overrides Sub Finalize()
        If mOleDbConnection.State <> ConnectionState.Closed Then mOleDbConnection.Close() : MessageBox.Show("1")

        MyBase.Finalize()
    End Sub
也报同样的错误。在这个过程中mOleDbConnection.State是打开的,执行的关闭的时候报错,垃圾回收压根就不是通过.Finalize进行
”在垃圾收集器释放某个对象之前,首先调用该对象的finalize方法“ 这段代码在if判断的时候mOleDbConnection还是存在的,一旦执行dispose或close方法,就说句柄不存在。。。。这个句柄是方法的句柄?还是对象的句柄? 现在的问题不是需不需要dispose的问题,而是为什么会报错的问题? 我仅仅希望在set nothing的时候关掉连接而已。。。。
楚狂歌 2014-10-28
  • 打赏
  • 举报
回复

 Protected Overrides Sub Finalize()
        If mOleDbConnection.State <> ConnectionState.Closed Then mOleDbConnection.Close() : MessageBox.Show("1")

        MyBase.Finalize()
    End Sub
也报同样的错误。在这个过程中mOleDbConnection.State是打开的,执行的关闭的时候报错,垃圾回收压根就不是通过.Finalize进行
五更琉璃 2014-10-27
  • 打赏
  • 举报
回复
引用 5 楼 sp1234 的回复:
在.net中,每当GC回收一个对象,必然会调用其 Dispose() 方法(如果有的话)。而释放你的对象之前,自然会去释放 mOleDbConnection。因此根本不用画蛇添足去调用 Dispose() 方法。 至于说“为什么在程序中需要调用 DbConnection 类型对象的 Dispose()方法?”,这是为了在宿主对象被销毁之前就提前、尽快地释放数据库连接,归还到连接池中,以免出现“连接池满”的异常。 而你的这段程序并没有这种需求,所以你也不需要调用 Dispose() 方法。
你说的不对吧, 在.net中,每当GC回收一个对象,必然会调用其 析构函数(如果有的话), 而Dispose() 方法是手动调用的
Tiger_Zhao 2014-10-27
  • 打赏
  • 举报
回复
Connection 对象用 Open、Close 来控制外部资源(连接)的占用和释放,这个要显式调用。
至于对象自身的 Dispose,由 .Net 自动完成,你只需要在必要时 Set Nothing 就可以了。

由于 Set Nothing 和 Dispose 之间有延时,如果你调用了 Open 而没有调用 Close,连接在 Dispose 之前是一直开着的。
所以要显式调用 Close。
楚狂歌 2014-10-27
  • 打赏
  • 举报
回复
@linyingnan @sp1234
楚狂歌 2014-10-27
  • 打赏
  • 举报
回复
连接从New cls开始打开,然后一直没有close,这样给GC回收有什么后果么?
  • 打赏
  • 举报
回复
在.net中,每当GC回收一个对象,必然会调用其 Dispose() 方法(如果有的话)。而释放你的对象之前,自然会去释放 mOleDbConnection。因此根本不用画蛇添足去调用 Dispose() 方法。 至于说“为什么在程序中需要调用 DbConnection 类型对象的 Dispose()方法?”,这是为了在宿主对象被销毁之前就提前、尽快地释放数据库连接,归还到连接池中,以免出现“连接池满”的异常。 而你的这段程序并没有这种需求,所以你也不需要调用 Dispose() 方法。
林英南 2014-10-24
  • 打赏
  • 举报
回复
Public NotInheritable Class OleDbConnection _ Inherits DbConnection _ Implements ICloneable, IDbConnection, IDisposable OleDbConnection本身就继承了IDisposable,不需要显性的销毁,.Net自己会把它干掉的,记得关闭connection就行了。
  • 打赏
  • 举报
回复
你的对象被销毁之前,自然会调用 mOleDbConnection.Dispose 代码,用不着你写什么代码。
拜一刀 2014-10-24
  • 打赏
  • 举报
回复
GC.Collect 方法 (Int32, GCCollectionMode),把mode设成Forced试试强制回收 不过强制回收据说好像容易出bug
楚狂歌 2014-10-24
  • 打赏
  • 举报
回复
难道GC.Collect?
第一部分 Visual Basic.net基础 1.vb. net介绍 2.vb.net的优点 3.新建一个vb.net项目 4.编写第一个vb.net应用程序 第二部分 vb.net的语法部分 1.vb.net的Numeric数据类型 2.vb.net的Byte数据类型 3.vb.net的String数据类型 4.vb.net的Boolean数据类型 5.vb.net的Date数据类型 6.vb.net的Object数据类型 7.vb.net的用户自定义类型 8.vb.net的数组定义 9.vb.net的数组列表 10.vb.net的多维数组 11.vb.net类型转换函数 第三部分 visual basic.net的运算 程序设计时经常用到的有6种运算:算术运算(Arithmetic)、赋值运算(Assignment)、二进制运算(Bitwise)、比较运算(Comparison)、连接运算(concatenation)及逻辑运算(Logical),下面对这6种运算进行简单介绍。 1.vb.net的算术运算 2.vb.net的赋值运算符 3.vb.net的二进制运算符 4.vb.net的比较运算符 5.vb.net的连接运算符和逻辑运算符 6.vb.net运算符的优先级 (一) Visual basic.net的常量和变量 1.vb.net的常量 2.vb.net的变量 (二) Visual basic.net的流程和控制结构 1.vb.net条件分支语句 2.vb.net的循环语句 (三) vb.net的过程和函数 1.vb.net的Sub过程 2.vb.net的Funtion过程 3.在vb.net中调用过程 4.如何向过程传递参数 (四)vb.net的类和对象基础 第四部分 visual basic.net的常用控件 1.vb.net的Label控件 2.vb.net的Button控件 3.vb.net的Textbox控件 4.vb.net的MainMenu控件 5.vb.net的Checkbox控件 6.vb.net的Radiobutton控件 7.vb.net的GroupBox控件 8.vb.net的PictureBox控件 9.vb.net的ListBox控件 10.vb.net的CheckedListBox控件 11.vb.net的Combobox控件 12.vb.net的ListView控件 13.vb.net的TreeView控件 14.vb.net的ImageList控件 15.vb.net的Timer控件 16.vb.net的HScrollBar和VScrollBar控件 17.vb.net的ProgressBar控件 18.vb.net的ToolBar控件 19.vb.net的StatusBar控件 20.Vs 2005的ToolStrip控件 21.Vs 2005的StatusStrip控件 22.Vs 2005的MenuStrip控件 第六部分 vb.net的OOP结构 1.什么是oop 2.vb.net的面向对象性 3.vb.net的共享成员(Share Members) 4.类模块和标准代码模块的区别和比较 5.对象浏览器 (一) 建立和使用对象 1.vb.net对象的建立和销毁对象的生命周期 2.设置和重设vb.net的属性 3.用方法来表现动作 4.vb.net对象变量的声明 5.对一个对象进行多种操作 6.使用New关键字 7.如何释放对对象的引用 8.如何把对象传递到一个过程 (二) 在程序运行中得到一个类的信息: 用一个字符名称调用一个属性或者方法 (三) vb.net中的类、继承与多态性 1.vb.net中给一个类添加方法 2.命名属性、方法和事件 3.vb.net的事件和事件处理 4.类的继承(Inheritance) 5.vb.net继承的规则 6.用继承建立一个继承类 7.重载Windows控件 8.什么时候使用继承 9.什么是命名空间(Namespace) 10.vb.net继承的例子 11.vb.net中用继承实现多态性 12.vb.net中用接口实现多态性 第七部分 数据库访问技术 关于SQL语言的知识,请参考: sql语言教程及Sql语言基础 1.数据库基础知识 2.vb.net数据集(Datasets)的概念 3.什么是dao 4.Dao与Jet数据库引擎 5.Dao对象模型 6.远程数据对象RDO 7.Rdo对象模型 8.odbc api是什么 9.ODBC的结构 10.使用ODBC API访问数据库 11.ado数据对象 12.ado对象模型 13.ADO.NET简介 14.使用ADO.NET的基本方法 第八部分 vb.net的多线程 1.自由线程(Free Threading) 2.关于线程的参数和返回值的问题 3.vb.net的并发性问题 第九部分 vb.net的文件和出错处理 1.vb.net的出错处理 2.vb.net的多种出错处理(Multiple Exceptions) 3.vb.net的文件对象(file object) 4.vb.net文件处理的出错处理 5.检测文件的结束(Testing for End of File) 6.文件的静态方法(Static File Methods)
vb.net基础教程 第一部分 Visual Basic.net基础 1.vb. net介绍 2.vb.net的优点 3.新建一个vb.net项目 4.编写第一个vb.net应用程序 第二部分 vb.net的语法部分 1.vb.net的Numeric数据类型 2.vb.net的Byte数据类型 3.vb.net的String数据类型 4.vb.net的Boolean数据类型 5.vb.net的Date数据类型 6.vb.net的Object数据类型 7.vb.net的用户自定义类型 8.vb.net的数组定义 9.vb.net的数组列表 10.vb.net的多维数组 11.vb.net类型转换函数 第三部分 visual basic.net的运算 程序设计时经常用到的有6种运算:算术运算(Arithmetic)、赋值运算(Assignment)、二进制运算(Bitwise)、比较运算(Comparison)、连接运算(concatenation)及逻辑运算(Logical),下面对这6种运算进行简单介绍。 1.vb.net的算术运算 2.vb.net的赋值运算符 3.vb.net的二进制运算符 4.vb.net的比较运算符 5.vb.net的连接运算符和逻辑运算符 6.vb.net运算符的优先级 (一) Visual basic.net的常量和变量 1.vb.net的常量 2.vb.net的变量 (二) Visual basic.net的流程和控制结构 1.vb.net条件分支语句 2.vb.net的循环语句 (三) vb.net的过程和函数 1.vb.net的Sub过程 2.vb.net的Funtion过程 3.在vb.net中调用过程 4.如何向过程传递参数 (四)vb.net的类和对象基础 第四部分 visual basic.net的常用控件 1.vb.net的Label控件 2.vb.net的Button控件 3.vb.net的Textbox控件 4.vb.net的MainMenu控件 5.vb.net的Checkbox控件 6.vb.net的Radiobutton控件 7.vb.net的GroupBox控件 8.vb.net的PictureBox控件 9.vb.net的ListBox控件 10.vb.net的CheckedListBox控件 11.vb.net的Combobox控件 12.vb.net的ListView控件 13.vb.net的TreeView控件 14.vb.net的ImageList控件 15.vb.net的Timer控件 16.vb.net的HScrollBar和VScrollBar控件 17.vb.net的ProgressBar控件 18.vb.net的ToolBar控件 19.vb.net的StatusBar控件 20.Vs 2005的ToolStrip控件 21.Vs 2005的StatusStrip控件 22.Vs 2005的MenuStrip控件 第六部分 vb.net的OOP结构 1.什么是oop 2.vb.net的面向对象性 3.vb.net的共享成员(Share Members) 4.类模块和标准代码模块的区别和比较 5.对象浏览器 (一) 建立和使用对象 1.vb.net对象的建立和销毁对象的生命周期 2.设置和重设vb.net的属性 3.用方法来表现动作 4.vb.net对象变量的声明 5.对一个对象进行多种操作 6.使用New关键字 7.如何释放对对象的引用 8.如何把对象传递到一个过程 (二) 在程序运行中得到一个类的信息: 用一个字符名称调用一个属性或者方法 (三) vb.net中的类、继承与多态性 1.vb.net中给一个类添加方法 2.命名属性、方法和事件 3.vb.net的事件和事件处理 4.类的继承(Inheritance) 5.vb.net继承的规则 6.用继承建立一个继承类 7.重载Windows控件 8.什么时候使用继承 9.什么是命名空间(Namespace) 10.vb.net继承的例子 11.vb.net中用继承实现多态性 12.vb.net中用接口实现多态性 第七部分 数据库访问技术 关于SQL语言的知识,请参考: sql语言教程及Sql语言基础 1.数据库基础知识 2.vb.net数据集(Datasets)的概念 3.什么是dao 4.Dao与Jet数据库引擎 5.Dao对象模型 6.远程数据对象RDO 7.Rdo对象模型 8.odbc api是什么 9.ODBC的结构 10.使用ODBC API访问数据库 11.ado数据对象 12.ado对象模型 13.ADO.NET简介 14.使用ADO.NET的基本方法 第八部分 vb.net的多线程 1.自由线程(Free Threading) 2.关于线程的参数和返回值的问题 3.vb.net的并发性问题 第九部分 vb.net的文件和出错处理 1.vb.net的出错处理 2.vb.net的多种出错处理(Multiple Exceptions) 3.vb.net的文件对象(file object) 4.vb.net文件处理的出错处理 5.检测文件的结束(Testing for End of File) 6.文件的静态方法(Static File Methods)

16,549

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧