Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.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# 何时调用DbConnection.StateChange?_C#_Sql Server_Sqlconnection - Fatal编程技术网

C# 何时调用DbConnection.StateChange?

C# 何时调用DbConnection.StateChange?,c#,sql-server,sqlconnection,C#,Sql Server,Sqlconnection,我有以下代码: class Program { static void Main() { var connection = new SqlConnection("myConnectionString"); connection.Open(); connection.StateChange += HandleSqlConnectionDrop; Console.WriteLine("Hi"); C

我有以下代码:

   class Program
{
    static void Main()
    {
        var connection = new SqlConnection("myConnectionString");
        connection.Open();
        connection.StateChange += HandleSqlConnectionDrop;
        Console.WriteLine("Hi");
        Console.ReadLine();
    }

    private static void HandleSqlConnectionDrop(object connection, StateChangeEventArgs args)
    {
        Console.WriteLine("DB change detected");
    }
}
我在SQL server实例运行时启动上述代码。然后我开始执行

SHUTDOWN WITH NOWAIT;
在程序连接到的sql server实例上。然后,我观察到SQL server服务停止。但是,我从未在输出中看到“DB change detected”消息。为什么会这样


旁白:如果我尝试在SQL连接上执行操作,我将看到StateChange处理程序被调用,但决不会在之前调用。有什么方法可以改变这种行为吗?

StateChange事件是针对连接的状态,而不是数据库服务器的实例。要获取数据库服务器的状态

当事件的状态从更改为时,将发生StateChange事件 关闭到打开,或打开到关闭

从MSDN:

如果你要为数据库滚动你自己的监视器,那么你可以考虑使用一个方法,如果连接是可用的,那么返回true /false,并在一个日程表上ping该方法。您甚至可以将一个方法包装成一个无休止的循环,在一段时间后重复,并在该“状态”发生更改时引发它自己的事件

下面是另一个答案的快速方法,这是一个简单的方法:

/// <summary>
/// Test that the server is connected
/// </summary>
/// <param name="connectionString">The connection string</param>
/// <returns>true if the connection is opened</returns>
private static bool IsServerConnected(string connectionString)
{
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        try
        {
            connection.Open();
            return true;
        }
        catch (SqlException)
        {
            return false;
        }
    }
}
//
///测试服务器是否已连接
/// 
///连接字符串
///如果连接已打开,则为true
私有静态bool IsServerConnected(字符串连接字符串)
{
使用(SqlConnection连接=新的SqlConnection(connectionString))
{
尝试
{
connection.Open();
返回true;
}
捕获(SqlException)
{
返回false;
}
}
}
资料来源:

何时调用DbConnection.StateChange

您可以通过查看Microsoft参考源代码找到答案

该事件由函数引发。查找此函数的引用只会产生几个实例:

首先,在
SqlConnection
类中,仅在方法中调用
OnStateChange

然后在文件中,有一个名为
DBCONNECTIONOBJECT
的分部类。它看起来像是用于所有使用一些构建时诡计的
DbConnection
派生类。因此,您可以认为它是 SqLink连接< /COD>的一部分。在任何情况下,它都只能从函数内部调用
OnStateChange

据我所知(部分类的胡说八道使其变得困难),
SqlConnection.SetInnerConnectionEvent
仅从调用。这叫做:

因此,总之,事件只是响应客户端操作而引发的,
SQLConnection
中内置的连接状态似乎没有任何轮询

有没有办法改变这种行为


看看源代码,我看不到。正如其他人所建议的,您当然可以实现自己的轮询。

“如果我尝试在SQL连接上执行操作,我将看到StateChange处理程序被调用”——事实上,您回答了您的问题。连接对象不ping服务器,仅在需要时检查状态。将
connection.Open()
放在
.StateChange+=…
之后,查看它是否有效。@AlexKudryashev SQL客户端和SQL server之间不应该存在某种保持活动状态的机制吗?我的理解是SqlConnection对象应该一对一地映射到SQLServer会话。如果服务器终止会话,有没有办法将该信息传递到我的代码中?您可以尝试使用无害的方式轮询服务器,如
select 1
,当您尝试向服务器发送sql命令时,通常会调用它,并且连接中断或超时。由于SqlConnection不能使服务器保持活动状态,您可能知道只有在尝试使用此连接执行命令时,状态才会发生更改。@v.chjen是否有一些官方文档可以向我指出,这些文档支持“SqlConnection不能使服务器保持活动状态”的观点?“StateChange事件用于连接的状态,而不是数据库服务器的实例。”->但如果服务器的状态更改,则连接的状态也应更改(即变为“不再可用”)但是连接不会检测到数据库服务器的状态变化,除非您实际对服务器进行查询,这就是为什么您应该有一个答案中提到的包装器,以便您能够可靠地识别真实的状态变化,而不仅仅是在您的应用程序层。