下面的这段程序,在.Net 1.1 中没有问题,但是到了2.0 中就有问题了,每次运行程序的时候都会报告需要调试,并指出 Myconn.Close(); 这一句有错误,意思大概是说.NET Framework Data Provider 出错。请问各位。我的这样写法有错误么?应该怎么样改进?=======================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;namespace TestLib
{
class dbcontrols
{
OleDbConnection Myconn = new OleDbConnection("Provider=SQLOLEDB;Data Source=127.0.0.1;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;pwd=sa");
OleDbCommand mycomm; public dbcontrols()
{
Myconn.Open();
}
~dbcontrols()
{
Myconn.Close();
Myconn.Dispose();
}
public bool Run(string runstr)
{ bool result = true;
try
{
mycomm = new OleDbCommand(runstr, Myconn);
mycomm.ExecuteNonQuery();
}
catch
{
result = false;
} return result;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;namespace TestLib
{
class dbcontrols
{
OleDbConnection Myconn = new OleDbConnection("Provider=SQLOLEDB;Data Source=127.0.0.1;Persist Security Info=True;User ID=sa;Initial Catalog=pubs;pwd=sa");
OleDbCommand mycomm; public dbcontrols()
{
Myconn.Open();
}
~dbcontrols()
{
Myconn.Close();
Myconn.Dispose();
}
public bool Run(string runstr)
{ bool result = true;
try
{
mycomm = new OleDbCommand(runstr, Myconn);
mycomm.ExecuteNonQuery();
}
catch
{
result = false;
} return result;
}
}
}
{
Myconn.Close();
Myconn.Dispose();
}改成 ~dbcontrols()
{
if(this.Myconn.State!=ConnectionState.Closed){
Myconn.Close();
Myconn.Dispose();
}
}
不过照理说你这么写应该没错阿,试试看
测试代码:
===================
public class Class1 : IDisposable
{
SqlConnection Myconn = new SqlConnection("Data Source=.;Initial Catalog=Morning2;Integrated Security=True");
SqlCommand mycomm; string bug;
public Class1()
{
Myconn.Open();
}
~Class1()
{
try
{
Myconn.Close();
Myconn.Dispose();
}
catch (Exception ee)
{
bug = ee.ToString();
}
} public string Run()
{
string flag="";
string runstr = "SELECT [DepartmentId], [DepartName] FROM [morning_Department]";
try
{
mycomm = new SqlCommand(runstr, Myconn);
flag = mycomm.ExecuteScalar().ToString();
}
catch
{ } return flag;
}
#region IDisposable 成员 public void Dispose()
{
//Myconn.Close();
//Myconn.Dispose();
} #endregion
}
========================
调用代码:
try
{
using (Class1 c = new Class1())//强制回收
{
string i = c.Run();
Response.Write("flag=" + i);
}
}
catch (Exception ee)
{ Response.Write(ee.ToString());
}
=======================建议改进方法:实现IDisposable接口,不要用析构函数。(参见代码中Dispose()函数里注销掉的2句,你可以删除析构函数,把相关代码放到这里。外部用using(){...}方式调用)
你可以在上述代码的析构函数和Dispose函数下断点,看看。
三层, 上面的代码是在 数据操作层上,方法比较少。但在逻辑层对数据层的调用上方法写的太多了,这样用 using 的方法,要改的地方太多了。有没有别的办法呢
~dbcontrols()
{
Myconn.Close();
Myconn.Dispose();
}改成 ~dbcontrols()
{
if(this.Myconn.State!=ConnectionState.Closed){
Myconn.Close();
Myconn.Dispose();
}
}
本人认为正解
实在需要析构的时候
protected override void Finalize()
{
try{关你的连接,释放你的非托管}
finally{base.Finalize();}
}
.net中的析构函数与C++中意义是不一样的。因为GC的垃圾收集是不可预测的。
而且
Myconn.Close();
Myconn.Dispose();
是重复使用。没必要如此一般地如果是托管资源,不必要自已进行释放,但在析构中可以使用
obj =null;
非托管资源实现IDisposable接口,手动释放。
Close是Dispose的包装。而且没理解ADO.net 与ADO的用法区别的意义
ADO.net没必要保持一个连接,SQL Server 支持连接池
ADO.net中一定要尽快地释放连接。
一般可以使用using来确保实现了IDisposable的对象的资源释放