重复的堆栈跟踪表示什么?

4

我有一个webservice,其中有一个webmethod被异步调用,它会根据不同的因素在固定时间间隔和随机时间内被调用(这基本上意味着它可以被多个事物随时调用)。这个webmethod在其主体内部多次调用数据库。有时候会出现超时、死锁和其他需要各种改进的迹象。不过这并不是很重要。我想问的是这个堆栈跟踪:

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()

需要注意的事项:

  1. PrivateMethod仅在WebMethod中的开头被调用一次
  2. 没有涉及到递归
  3. PrivateMethod只是调用存储过程并返回结果。
  4. 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。不知道这是否重要。


1
你能发布该方法的内容以及调用它的代码吗? - Adam Houldsworth
4
更重要的是发布引起这种情况的代码。我无法想象任何多线程代码可能导致出现这样奇怪的堆栈跟踪,我想看看代码,看看是否有微妙的原因你可能会忽略。 - Adam Houldsworth
@Dennis的WebMethod整个主体都包含在try-catch块中,如果捕获到异常,则会发送一封电子邮件,其内容基本上是exception.ToString()。 - S_F
@S_F:您能发布 WebMethod 中的 catch 块代码吗? - Dennis
@S_F 不幸的是,我没有更多要补充的了。 - Adam Houldsworth
显示剩余5条评论
1个回答

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;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接