我有一个带有webmethod的web服务,它以设定的时间间隔异步调用,并根据不同的因素随机调用(这基本上意味着它可以随时被多个事件调用)。这个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()
注意事项:
此问题不仅限于PrivateMethod,但似乎与SqlConnection.Open有关。它也很少发生,并且是我前面提到的超时/死锁问题的一小部分 - 所有其他情况都有正常的堆栈跟踪。
任何可能导致重复堆栈跟踪的想法?正如我所说,那里的代码没有递归,我的私有方法无法从.NET库中调用。
编辑: 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。不知道是否重要。
答案 0 :(得分:0)
这应该可以修复你的线程问题 将static 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;
}