请帮我分析一下面的代码,代码的运行是正常的,但有时会出现数据库无法关闭退出.现象是,如果xxx.mdb数据库已被Access2000打开,那么运行下面的代码将会出错,并且造成数据再也无法关闭,双击xxx.mdb数据库文件,显示"文件正在使用,无法打开".强制结束有关的线程,可以重新正常运行程序,但这时出现的现象更怪,就是:下面的代码第一次被调用,运行是正常,但在短时(几秒到几十秒)内再次调用,就不正常,出错于"Mysjk.Open(Sjkf,null,null,-1);"这一句,错误为"未知错误",但如等一到两分钟后再调用,又会恢复正常,跟着调用便双会出错,如此每两次调用之间都要隔一到两分钟,估计是数据库被打开后没有及时关闭,要等一到两分钟才会关闭.但如果这种现象在重新启动系统后便会消失,如果重启系统,无论如何调用它,都不会出错.为什么会出现这种现象呢?怎样解决!请高手指教!
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;namespace WebForm
{
/// <summary>
/// select 的摘要说明。
/// </summary>
public class select : System.Web.UI.Page
{
ADODB._Connection Mysjk=new ADODB.ConnectionClass();
bool openok=false;
private void Page_Load(object sender, System.EventArgs e)
{
string Uc="";
Uc=(string)this.Session["UserClass"];
if (Uc==null || Uc=="")
{
this.Page.Response.Write("对不起,你没有查看该页的权限。");
Response.End();
}
else
{
try
{
string Sjkf;
if (openok==false)
{
Sjkf = "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" + Server.MapPath("xxxx.mdb") + ";";
Mysjk.Open(Sjkf,null,null,-1);
openok=true;
} string SqlMode=this.Request["SqlMode"];
string Etxt="";
switch (SqlMode)
{
//一些具体读库写库操作
} } catch(Exception error)
{
try
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error.Message);
Mysjk.Close();
}
catch(Exception error2)
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error2.Message);
}
}
}
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;namespace WebForm
{
/// <summary>
/// select 的摘要说明。
/// </summary>
public class select : System.Web.UI.Page
{
ADODB._Connection Mysjk=new ADODB.ConnectionClass();
bool openok=false;
private void Page_Load(object sender, System.EventArgs e)
{
string Uc="";
Uc=(string)this.Session["UserClass"];
if (Uc==null || Uc=="")
{
this.Page.Response.Write("对不起,你没有查看该页的权限。");
Response.End();
}
else
{
try
{
string Sjkf;
if (openok==false)
{
Sjkf = "Driver={Microsoft Access Driver (*.mdb)}; DBQ=" + Server.MapPath("xxxx.mdb") + ";";
Mysjk.Open(Sjkf,null,null,-1);
openok=true;
} string SqlMode=this.Request["SqlMode"];
string Etxt="";
switch (SqlMode)
{
//一些具体读库写库操作
} } catch(Exception error)
{
try
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error.Message);
Mysjk.Close();
}
catch(Exception error2)
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error2.Message);
}
}
}
_____________________________________________
为什么呢?
我想出现不能自动关闭时,Mysjk.Close()是执行了的.其实我的结构简化了可以这样表示:
try //代码被正常执行
{
Mysjk.Close()
}
catch(Exception error) //代码执行出错
{
Mysjk.Close()
} 这样,无论代码执行正常与否,Mysjk.Close()都会被执行,不知楼上说的要放到放到finaly块里是何道理呢?
try //代码被正常执行
{
……
}
finaly
{
Mysjk.Close()
}
也是不能解决问题的,因为这样需然保证了Mysjk.Close()被执行,但
try //代码被正常执行
{
Mysjk.Close()
}
catch(Exception error) //代码执行出错
{
Mysjk.Close()
}
也同样保证了Mysjk.Close()被执行呀!
{
// 你的操作
}
catch(Exception error) //代码执行出错
{
Mysjk.Close()
}
finally
{
Mysjk.Close();
}
Mysjk是用new来创建的,凡用new创建的对象,是不是都被C#托管呢?Mysjk延尽关闭会不会是由于C#的托管引起的?
参见msdn
ms-help://MS.MSDNQTR.2003FEB.2052/cpref/html/frlrfsystemdataoledboledbconnectionclassclosetopic.htm
finally
{
Mysjk.Close();
}
catch(Exception error) //代码执行出错
{
Mysjk.Close()
}
中去掉Mysjk.Close(),则出错后数据库永远无法关闭,除非重新启动计算或强制结束一些与NET有关的线程。如果Mysjk.Close()存在的话,数据库不是无法关闭,而是要等一两分钟才关闭,这也说明Mysjk.Close()是执行了的,但却没有立即生效,是什么原因呢?————————————————————————————————
connection的close应该放在finally块里面,不然有可能发生两次close而产生错误的.
---------------------------------------------------------------
这个问题我已考虑了,实际上我已经对此作出了处理:
catch(Exception error)
{
try
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error.Message);
Mysjk.Close();
}
catch(Exception error2) //第二次出错检测,就是专门处理这个问题的。
{
this.Page.Response.Write("Error"+(char)13);
this.Page.Response.Write(error2.Message);
}
}
}
————————————————————————————————————
因为出错于"Mysjk.Open(Sjkf,null,null,-1);"这一句,错误为"未知错误"。
现在我想直接杀掉Mysjk对象,而不让C#去托管,该怎样做?
出错后,线程管理器中有几个关net的线程没有结束,如果人为结束这些线程则一切又会恢复正常。
你想呀,一个文件,怎么可能一个人打开,一个人关闭呢?尤其是数据库!