重复堆栈跟踪意味着什么?

What can a repeating stack trace mean?

提问人:S_F 提问时间:11/18/2013 最后编辑:S_F 更新时间:4/30/2014 访问量:250

问:

我有一个带有 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()

注意事项:

  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。不知道这是否重要。

C# net-2.0 堆栈跟踪 SQLException

评论

1赞 Adam Houldsworth 11/18/2013
你能发布方法内容和调用它的内容吗?
0赞 S_F 11/18/2013
哪种方法?PrivateMethod 是在 WebMethod 的开头调用的,只不过是标准 - 使用 SqlConnection,声明和定义 SqlCommand,添加参数,打开连接,执行非查询,返回结果。真的有必要显示确切的代码吗?
4赞 Adam Houldsworth 11/18/2013
发布所谓的内容可能更重要。我想不出任何与多线程代码有关的事情会导致这种奇怪的堆栈跟踪,我想看看代码,看看是否有您可能遗漏的微妙原因。
0赞 Dennis 11/18/2013
如何获取此堆栈跟踪?这是您在调试器的异常详细信息中看到的内容,还是您从任何日志中读取的内容?
0赞 S_F 11/18/2013
@AdamHouldsworth 什么叫 WebMethod?据我所知,它是一个简单的控制台应用程序,它被调用各种数据集,并为一组中的每个项目调用 WebMethod。不过,我不知道该应用程序究竟是如何使用的。

答:

0赞 Matas Vaitkevicius 4/30/2014 #1

这应该可以解决您的线程问题 将静态 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;
    }