Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果我在方法中使用SqlCommand作为参数,它会阻止SqlConnection吗?_C#_Sql Server_Sqlconnection_Sqlcommand - Fatal编程技术网

C# 如果我在方法中使用SqlCommand作为参数,它会阻止SqlConnection吗?

C# 如果我在方法中使用SqlCommand作为参数,它会阻止SqlConnection吗?,c#,sql-server,sqlconnection,sqlcommand,C#,Sql Server,Sqlconnection,Sqlcommand,我的服务出现了连接池问题(已达到最大值),无论我在哪里尝试打开连接,我都会使用语句将其包装在一个上,以正确地处理它,但我认为有些事情不允许它工作。我认为这是因为我使用的方法期望SqlCommand作为参数,这是一个示例: private void QueryDB(string sConnString, SqlCommand oComm) { using (SqlConnection connection = new SqlConnection(sConnString)) {

我的服务出现了连接池问题(已达到最大值),无论我在哪里尝试打开连接,我都会使用语句将其包装在一个
上,以正确地处理它,但我认为有些事情不允许它工作。我认为这是因为我使用的方法期望
SqlCommand
作为参数,这是一个示例:

private void QueryDB(string sConnString, SqlCommand oComm)
{
    using (SqlConnection connection = new SqlConnection(sConnString))
    {
        try
        {
            connection.Open();
            oComm.Connection = connection;
            oComm.CommandTimeout = 2;
            oComm.ExecuteNonQuery();
        }
        catch (SqlException e)
        {
            //log exception
        }
        catch (Exception e)
        {
            //log exception
        }
    }
}
之所以这样做,是因为我需要在该方法之外组装参数,如下所示:

public void Example1()
{
    using (SqlCommand command = new SqlCommand())
    {
        command.CommandText = "SELECT TOP 1 FROM Table ORDER BY column1 DESC";
        QueryDB(_connString, command));
    }
}

public void Example2()
{
    SqlCommand command= new SqlCommand();
    command.CommandText = "UPDATE Table set column1 = @value where column2 = @number";
    command.Parameters.Add(new SqlParameter { ParameterName = "@value", Value = "someValue", SqlDbType = SqlDbType.VarChar });
    command.Parameters.Add(new SqlParameter { ParameterName = "@number", Value = 3, SqlDbType = SqlDbType.Int });

    QueryDB(_connString, command));
}

Example1
中,我尝试处理
SqlCommand
,但我不知道它是否可以这样工作。另一件需要考虑的事情是,我每秒运行一个计时器,执行
Example1
Example2
,我不知道这是否与问题有关,最大池大小错误有时会发生,不是每天都会发生,它会延迟其他查询。我能做些什么来改善这种行为吗?谢谢

我真的不知道这是否能解决您在连接池问题上的问题,但是,在@Jack A对您的问题的评论上,也许可以进一步扩展一下,构造代码的更好方法是将
QueryDB
方法更改为接受一个委托,该委托使用必要的信息更新
SqlCommand
变量,然后,您可以确保
SqlConnection
SqlCommand
在该方法中得到正确处理

private void QueryDB(string sConnString, Action<SqlCommand> commandDelegate)
{
    using (SqlConnection oCon = new SqlConnection(sConnString))
        using(SqlCommand oComm = new SqlCommand())
        {
            try
            {
                oCon.Open();
                oComm.Connection = oCon;
                oComm.CommandTimeout = 2;
                commandDelegate(oComm);
                oComm.ExecuteNonQuery();
            }
            catch (SqlException e)
            {
                //log exception
            }
            catch (Exception e)
            {
                //log exception
            }
        }
}

再说一次,我不确定这是否能解决您的池问题,但它确保了至少所有内容都整齐地包装在您的
QueryDB
方法中。

我要感谢大家的回答!在做了大量的研究和修改之后,我实现了@Jack a和@Jhon Busto的建议。但是你知道,John,它没有解决连接池的问题,事实证明,真正的问题是计时器,我没有注意到它一直在执行
Example1
Example2
,但不是每秒钟执行一次,而是每50毫秒或更短,所以我假设它在池中创建了很多连接。我正在更改计时器的
计时器.Interval
属性,但我不知道:

如果Enabled和AutoReset都设置为false,并且计时器以前已启用,则设置Interval属性会导致引发一次已用事件,就像Enabled属性已设置为true一样。要在不引发事件的情况下设置间隔,可以临时将Enabled属性设置为true,将interval属性设置为所需的时间间隔,然后立即将Enabled属性设置回false

资料来源:


因此,如果我需要更改
计时器.Interval
我遵循了微软的文档,我再次测试了所有东西,结果一切正常。使用计时器时要小心!呵呵:)

尝试手动处理或尝试
SqlCommand.Cancel()
endexecutenquery()执行命令需要多长时间?如果每秒都运行它们,它们占用一秒钟以上的时间,则可能会遇到问题,因为有太多的并行运行。而不是在<代码> Sql命令< /Calp>实例中,考虑传递被调用的委托来填充命令,并在内部构造命令实例。可能是您的应用程序死锁堆积。在SSMS中,连接到实例并使用Monitor视图查看活动查询和打开的连接。您应该能够检查状态。他们都在等吗,或者是别的什么?这应该会让你对实际发生的事情有更多的了解,但是你在上面的问题中展示的代码不应该保留任何开放的托管连接。可能存在一些由.net CLR池化的非托管连接,但如果您的应用程序正在正常执行,则这些连接应该是最小的。
public void Uses()
{
    QueryDB(_connString, (oComm) => oComm.CommandText = "SELECT TOP 1 FROM Table ORDER BY column1 DESC");

    QueryDB(_connString, longerDelegate);
}

private void longerDelegate(SqlCommand oComm)
{
    oComm.CommandText = "UPDATE Table set column1 = @value where column2 = @number";
    oComm.Parameters.Add(new SqlParameter { ParameterName = "@value", Value = "someValue", SqlDbType = SqlDbType.VarChar });
    oComm.Parameters.Add(new SqlParameter { ParameterName = "@number", Value = 3, SqlDbType = SqlDbType.Int });
}