多线程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;
        }
    }
}

多线程WCF与ADO.. NET和SQL Server连接会抛出“当读取器关闭时,试图调用Read无效”

几件事

  • 在引用连接时使用command.Connection_connection -看起来不像它们是相同的实例。

  • using语句包裹在Connection对象周围以保持一致,而不是显式地调用Dispose()

  • 呼叫_connection.Open()时不要检查ConnectionState。永远打开,永远关闭。数据提供程序将在必要时处理连接池。

  • 在完成DataReader后通过调用reader.Read()关闭DataReader

  • 您使用DataReader后没有关闭连接。始终通过在ExecuteReader()方法中传递CommandBehavior.CloseConnection或在所有数据访问后调用_connection.Close()显式关闭它。