多线程WCF与ADO.. NET和SQL Server连接会抛出“当读取器关闭时,试图调用Read无效”
本文关键字:读取 无效 Read 调用 NET ADO WCF SQL Server 连接 多线程 | 更新日期: 2023-09-27 18:18:14
我有一个连接到SQL Server数据库的WCF服务。
WCF代码:[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyWebService : IMyWebService
{
public IList<IDictionary<string, object>> Select()
{
return nee MyRepository().Select("SELECT A, B, C FROM TABLE_T");
}
}
库代码:
public IList<IDictionary<string, object>> Select(string sqlQuery, params SqlParameter[] pars)
{
IList<IDictionary<string, object>> list = new List<IDictionary<string, object>>();
using (SqlCommand command = new SqlCommand(sqlQuery, Connection))
{
command.Parameters.AddRange(pars);
if (command.Connection.State == ConnectionState.Closed)
command.Connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
IDictionary<string, object> keyPair = new Dictionary<string, object>();
for (int i = 0; i < reader.FieldCount; i++)
keyPair.Add(reader.GetName(i), reader.GetValue(i));
list.Add(keyPair);
}
}
command.Parameters.Clear();
_connection.Dispose();
_connection = null;
}
return list;
}
当只有一台机器调用时可以正常工作,但是当两台或两台以上的机器调用时,我得到一个错误
reader关闭时调用Read无效
和SQL Server连接失败,直到重启。
PS:我真正的web服务代码执行更多的操作,如插入和更新。对于每个操作,我都创建一个到数据库服务器的新连接,并且总是在命令周围加上using
。
更新1:(在评论中请求)
我的连接代码:
private SqlConnection _connection = null;
protected SqlConnection Connection
{
get
{
try
{
if (string.IsNullOrWhiteSpace(_connectionString))
throw new NotImplementedException("Missing _connectionString");
if (_connection == null)
_connection = new SqlConnection(_connectionString);
if (_connection.State == ConnectionState.Closed)
_connection.ConnectionString = _connectionString;
_connection.Open();
return _connection;
}
catch (Exception e)
{
_lastConnectErrorMessage = e.Message;
throw e;
}
}
}
几件事
-
在引用连接时使用
command.Connection
或_connection
-看起来不像它们是相同的实例。 -
将
using
语句包裹在Connection对象周围以保持一致,而不是显式地调用Dispose()
-
呼叫
_connection.Open()
时不要检查ConnectionState
。永远打开,永远关闭。数据提供程序将在必要时处理连接池。 -
在完成
DataReader
后通过调用reader.Read()
关闭DataReader
-
您使用
DataReader
后没有关闭连接。始终通过在ExecuteReader()
方法中传递CommandBehavior.CloseConnection
或在所有数据访问后调用_connection.Close()
显式关闭它。