我写的代码运行时,经常报错,有时是这个错误:
ExecuteReader 要求已打开且可用的连接。连接的当前状态为正在连接。偶尔会出现另外一个错误:
已有打开的与此命令相关联的 DataReader,必须首先将它关闭。刚刚又测试,偶尔又会出现一个错误:
阅读器关闭时尝试调用 Read 无效。而偶尔也会正常运行,不过次数很少而我只是使用Thread调用我的代码里的ExecuteDataTable方法
就一直报错
我的SqlHelper代码如下:
public virtual void ExecuteDataTable(ref DataTable refDt, string sql)
{
if (refDt == null)
{
refDt = new DataTable("DataTable1");
}
using (DbCommand com = CreateCommand())
{
try
{
// 创建数据库连接,并指向Command
DbConnection con = OpenConnection();
com.Connection = con;
com.CommandText = sql; com.CommandType = CommandType.Text; DbDataAdapter dap = CreateAdapter();
dap.SelectCommand = com; dap.Fill(refDt);
}
catch (Exception e)
{
throw e;
}
finally
{
CloseConnection(com.Connection);
}
}
}
protected override DbConnection OpenConnection()
{
connection = new SqlConnection(ConnectionString);
connection.Open();
return connection;
}public override DbDataAdapter CreateAdapter()
{
DbDataAdapter dap = new SqlDataAdapter();
return dap;
}public override DbCommand CreateCommand()
{
DbCommand ret = new SqlCommand();
return ret;
}
protected virtual void CloseConnection(DbConnection con)
{
if (con != null && con.State != ConnectionState.Closed)
{
con.Close();
//con.Dispose();
con = null;
}
}
ExecuteReader 要求已打开且可用的连接。连接的当前状态为正在连接。偶尔会出现另外一个错误:
已有打开的与此命令相关联的 DataReader,必须首先将它关闭。刚刚又测试,偶尔又会出现一个错误:
阅读器关闭时尝试调用 Read 无效。而偶尔也会正常运行,不过次数很少而我只是使用Thread调用我的代码里的ExecuteDataTable方法
就一直报错
我的SqlHelper代码如下:
public virtual void ExecuteDataTable(ref DataTable refDt, string sql)
{
if (refDt == null)
{
refDt = new DataTable("DataTable1");
}
using (DbCommand com = CreateCommand())
{
try
{
// 创建数据库连接,并指向Command
DbConnection con = OpenConnection();
com.Connection = con;
com.CommandText = sql; com.CommandType = CommandType.Text; DbDataAdapter dap = CreateAdapter();
dap.SelectCommand = com; dap.Fill(refDt);
}
catch (Exception e)
{
throw e;
}
finally
{
CloseConnection(com.Connection);
}
}
}
protected override DbConnection OpenConnection()
{
connection = new SqlConnection(ConnectionString);
connection.Open();
return connection;
}public override DbDataAdapter CreateAdapter()
{
DbDataAdapter dap = new SqlDataAdapter();
return dap;
}public override DbCommand CreateCommand()
{
DbCommand ret = new SqlCommand();
return ret;
}
protected virtual void CloseConnection(DbConnection con)
{
if (con != null && con.State != ConnectionState.Closed)
{
con.Close();
//con.Dispose();
con = null;
}
}
for(int i=0;i<10;i++){
new Thread(AddColumns).Start(tb);
}private void AddColumns(string tb){
DataTable a = null;
string sql = "select * from " + tb;
ExecuteDataTable(a, sql);
}
for(int i=0;i<10;i++){
new Thread(AddColumns).Start(tb);
}
哪位多线程的大侠指导一下吧而且使用SqlServer2005的活动监视器发现,那些出错的线程中创建的连接,怎么都没有关闭,还在AWAITING_COMMAND中
我觉得这里面
protected override DbConnection OpenConnection()
{ }
protected virtual void CloseConnection(DbConnection con)
{ }
这2个都没有作用么似乎.SqlDataAdapter adp = new SqlDataAdapter("selectCommand", "connString");
DataSet ds = new DataSet();
adp.Fill(ds);
这样就好了么
我在OpenConnection方法里,使用的是类成员变量:connection 然后在多线程里,多次使用同一个实例的这个成员变量来进行操作
在执行的时候,这个成员变量就可能刚被打开,又被另一个线程调用了
看来每次都要定义一个新的变量才行
Singleton模式只能有一个实例
数据库连接用后要及时释放,以供其他的连接使用,
protected override DbConnection OpenConnection()
{
DbConnection connection = new SqlConnection(ConnectionString);
connection.Open();
return connection;
}散分散分
但是因为使用的是同一个实例的同一个成员变量
导致a线程正在用这个成员操作的时候,b线程把这个成员的值修改了
此时a线程去关闭连接的时候,关闭了b的连接,导致b出错了并不是没有及时关闭连接的原因。
因为在OpenConnection方法中修改了它的值,导致线程操作起了冲突。