【问题标题】:SqlCommand timeout in C# MMO applicationC# MMO 应用程序中的 SqlCommand 超时
【发布时间】:2018-03-11 19:16:17
【问题描述】:

我有一个以异步方式使用 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();
}

【问题讨论】:

  • 36 小时过去了,没有更新...进展如何?
  • 进展如何?我的回答没有有用吗?
  • @Richardissimo 还没有。我已经更改了代码的某些部分并在套接字部分使用 while true 并检查同步套接字。等待结果
  • @Richardissimo 我为无法关闭的收藏找到了另一种解决方案。 sqlconnection.clearallpool()

标签: c# sql-server connection-timeout tcpsocket mmo


【解决方案1】:

主要问题是当我的程序在大约 30 分钟的大量请求下运行时,

为了隔离超时的根本问题,我建议测试30分钟独立于TCP套接字调用的存储过程的sql查询 并记录超时异常详细信息以供检查

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

【讨论】:

    【解决方案2】:

    由于看不到“//一些代码”,我将根据我们可以看到的有限的Sql相关代码的编写方式进行远景。

    我猜想SqlCommand、DataReader、SqlDataAdapter、TransactionScope 等一些一次性的东西不在“使用”块中,所以在数据库上保持资源是打开的。

    还值得提出这种问题的可能性,即问题中显示的代码或访问该数据库的任何其他程序,包括您自己的应用程序和 SSMS(例如,如果开发人员有一个未提交的事务在一个窗口)。

    附:我建议删除 using 块中的所有内容,除了“//一些代码”部分。

    添加更多代码后更新

    这是您更正后的代码。这将确保资源得到处理,从而防止可能导致您的问题的资源泄漏。

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

    附:永远不要写“扔前”;再次从内部捕获。它会导致堆栈跟踪丢失 - 只需使用“throw;”。

    【讨论】:

    • 你的意思是SqlDataAdapter可能会泄露资源,应该在使用???可能是SQL命令超时的原因?
    • 我会测试它,如果它不会再次发生,我会接受你的问题。希望它有效。谢谢
    • 另一个问题。我应该使用我在程序中使用的每个 dll 的发布版本并构建发布版本吗?是否与问题有关?
    • 首先要感谢你的同理心,是的,我真的压力很大,不得不说我的程序使用了另一个DLL,它必须有SqlConnections。我编辑了使用另一个 DLL 的代码。 //执行一些代码并连接到 SQL 服务器之后的行
    猜你喜欢
    • 1970-01-01
    • 2010-12-15
    • 2017-07-02
    • 1970-01-01
    • 2018-03-27
    • 2013-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多