我有一个以异步方式使用TCP套接字的C#项目。
每个请求都来自客户端并从SQL Server存储过程中提出问题,在问题结束后打开和关闭SQL连接。
我用过这段代码:
using (var con = new SqlConnection(setting.ConnectionString))
{
try
{
//some codes (edited)
SqlCommand command = new SqlCommand(con);
command.CommandText = "procedurename1";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@name", sb.ToString()));
SqlDataAdapter adapter = new SqlDataAdapter(command);
try
{
adapter.Fill(dataSet);
}
catch (Exception ex)
{
con.Close();
con.Dispose();
throw ex;
}
finally {
con.Close();
con.Dispose();
}
}
catch(Exception ex)
{}
finally
{
con.close();
con.dispose();
}
}
我用过
netstat -a -n | find /c "1433"
计算SQL连接的开启和关闭。
问题是SQL连接数增加,很少减少和倒计时。
主要问题是,当我的程序在大约30分钟的大量请求下工作时,我得到了
SqlCommand超时错误(默认为30秒)
重启我的C#程序后,SqlCommand
超时将消失。
这是我的程序还是SQL Server方面的问题?
请记住,它始终在SQL Server中调用存储过程,而不是执行查询 直接
主要方法:
public void main()
{
Task.Factory.StartNew(() =>
{
allDone.Reset();
mySocket.AcceptAsync(e);
allDone.WaitOne();
});
}
public void e_Completed(object sender, SocketAsyncEventArgs e)
{
var socket = (Socket)sender;
ThreadPool.QueueUserWorkItem(HandleTcpRequest, e.AcceptSocket);
e.AcceptSocket = null;
socket.AcceptAsync(e);
}
public void HandleTcpRequest(object state)
{
//do some code and connection to SQL server
DLL.Request httprequest = new DLL.Request(dataSet.Tables[0], fileDt);
DLL.IHttpContext _context = new DLL.HttpContext(httprequest);
_context.GetResults();
}
答案 0 :(得分:1)
我将根据我们可以看到的有限的Sql相关代码的编写方式进行远景,因为我们看不到“//某些代码”。
我猜想SqlCommand,DataReader,SqlDataAdapter,TransactionScope等一些不可用的东西不在'使用'块中,所以在数据库中保持资源打开。
也许值得提出这样的问题可能出现在问题中显示的代码或访问该数据库的任何其他程序,包括您自己的应用程序和SSMS(例如,如果开发人员运行了未提交的事务)一个窗口)。
P.S。我建议删除使用块中的所有内容,除了“// some codes”部分。
添加更多代码后更新
这是修正后的代码。这将确保处置资源,这将防止可能导致您的问题的泄漏资源。
using (var con = new SqlConnection(setting.ConnectionString))
{
//some codes (edited)
using (SqlCommand command = new SqlCommand(con))
{
command.CommandText = "procedurename1";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("@name", sb.ToString()));
using (var adapter = new SqlDataAdapter(command))
{
adapter.Fill(dataSet);
}
}
}
P.S。不要写“扔前”;从一个捕获内部再次。它会导致堆栈跟踪丢失 - 只需使用“throw;”。
答案 1 :(得分:1)
主要问题是,当我的程序在大约30分钟的大量请求下工作时,
为了隔离超时的根问题,我建议测试独立于TCP套接字调用的存储过程的sql查询30分钟 并记录检查的超时异常详细信息
在30分钟内运行以下查询以模拟您的工作环境:
public void RunQuery()
{
using (var con = new SqlConnection(setting.ConnectionString))
{
try
{
//some codes
}
catch(SqlException ex)
{
//test for timeout
if (ex.Number == -2) {
Console.WriteLine ("Timeout occurred");
// log ex details for more inspection
}
}
}
}
阅读How to handle the CommandTimeout properly?
当您使用异步调用时,我建议您尝试使用基于任务的异步编程模型进行异步数据库调用(TAP)