我有一个带有 webmethod 的 web 服务,它在设定的时间间隔内异步调用,并且根据不同的因素随机调用(这基本上意味着它可以在任何时间被多种事物调用)。此 web 方法在其主体内多次调用数据库。我有时会遇到超时、死锁和其他各种改进必要性的迹象。虽然这不是很相关。我想问的是这个堆栈跟踪:

System.Data.SqlClient.SqlException: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)
   at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at MyWebservice.PrivateMethod()
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at MyWebservice.PrivateMethod()
   at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
   at System.Data.SqlClient.SqlConnection.Open()
   at MyWebservice.PrivateMethod()
   at MyWebservice.WebMethod()

注意事项:
  • PrivateMethod 在 WebMethod 中只被调用一次,从一开始
  • 不涉及递归
  • PrivateMethod 无非是调用存储过程并返回结果。
  • PrivateMethod 中只使用了一个 SqlConnection 对象,并且只有一个 SqlConnection.Open 调用。

  • 此问题不仅限于 PrivateMethod,而且似乎与 SqlConnection.Open 相关。它也很少发生,并且是我之前提到的超时/死锁问题的很小一部分 - 所有其他情况都有正常的堆栈跟踪。

    任何可能导致重复堆栈跟踪的想法?正如我所说,那里的代码中没有递归,也无法从 .NET 库内部调用我的 PrivateMethod。

    编辑:
    PrivateMethod 看起来像这样:
    using SqlConnection connection = new SqlConnection(connectionString)
    {
        SqlCommand command = new SqlCommand("SP name here", connection);
        command.CommandType = CommandType.StoredProcedure;
        command.Parameters.AddWithValue("@paramName", _param);
        // several other parameters added the same way here
    
        SqlParameter result = new SqlParameter();
        result.ParameterName = "@result";
        result.DbType = DbType.Boolean;
        result.Direction = ParameterDirection.Output;
        command.Parameters.Add(result);
    
        connection.Open();
        command.ExecuteNonQuery();
    
        try { _spresult = (bool)result.Value; }
        catch (InvalidCastException) { return true; }   // this is by design, please don't pester me about it
    
        return _spresult;
    }
    

    如果 WebMethod 的参数之一设置为 true,它就会在 WebMethod 的最开始被调用,否则它根本不会被调用。

    编辑 2:忘了提及,它是 .NET 2.0。不知道是否重要。

    最佳答案

    这应该可以解决您的线程问题
    将静态 lockObj 添加到类中

    var isIdle = true;
    
    if (isIdle)
            {
                lock (padlock)
                {
                    if (isIdle)
                    {
                      isIdle = false;
    using SqlConnection connection = new SqlConnection(connectionString)
    {
    SqlCommand command = new SqlCommand("SP name here", connection);
    command.CommandType = CommandType.StoredProcedure;
    command.Parameters.AddWithValue("@paramName", _param);
    // several other parameters added the same way here
    
    SqlParameter result = new SqlParameter();
    result.ParameterName = "@result";
    result.DbType = DbType.Boolean;
    result.Direction = ParameterDirection.Output;
    command.Parameters.Add(result);
    
    connection.Open();
    command.ExecuteNonQuery();
    
    try { _spresult = (bool)result.Value; }
    catch (InvalidCastException) { return true; }   // this is by design, please don't pester me about it
    
    }
                    }
                }
            }
            return _spresult;
        }
    

    10-08 07:14