什么时候调用DbConnection.StateChange?

时间:2016-05-25 16:32:15

标签: c# sql-server sqlconnection

我有以下代码:

   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服务器实例运行时启动上面的代码。然后我继续执行

SHUTDOWN WITH NOWAIT;

在程序所连接的sql server实例上。然后我观察SQL服务器停止。但是,我从未看到检测到的" DB更改"输出中的消息。这是为什么?

旁白:如果我然后尝试对SQL连接执行操作,我将看到调用StateChange处理程序,但从未提前。有没有办法可以改变这种行为?

2 个答案:

答案 0 :(得分:10)

  

什么时候调用DbConnection.StateChange?

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

StateChange函数引发了DbConnection.OnStateChange事件。寻找对此函数的引用仅产生几个实例:

首先,在SqlConnection课程中,仅Close方法调用OnStateChange

然后在DbConnectionHelper.cs文件中,有一个名为DBCONNECTIONOBJECT的部分类。它看起来像是用于所有DbConnection派生类,使用了一些构建时间的恶作剧。所以你可以认为它是SqlConnection的一部分。在任何情况下,它仅从SetInnerConnectionEvent函数中调用OnStateChange

据我所知(部分类无意义使得困难),SqlConnection.SetInnerConnectionEvent仅从SqlConnectionFactory.SetInnerConnectionEvent调用。并且

调用

因此,总而言之 - 事件仅在响应客户端操作时引发 - 似乎没有对SQLConnection内置的连接状态进行任何轮询。

  

有没有办法可以改变这种行为?

查看源代码,我看不到一个。正如其他人所建议的那样,你当然可以实施自己的民意调查。

答案 1 :(得分:3)

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

  

当事件的状态发生变化时,会发生StateChange事件   关闭打开,或打开关闭。

来自MSDN:https://msdn.microsoft.com/en-us/library/system.data.common.dbconnection.statechange(v=vs.110).aspx

如果您要为数据库滚动自己的监视器,那么您可以考虑使用一种方法,如果连接可用则返回true / false并按计划ping该方法。你甚至可以用一个方法来包装一个方法,在一段时间后重复一次无限循环,并在这个"状态"之后提升它自己的事件。真的改变了。

这是一个来自另一个SO答案的快速方法,这是一个简单的方法:

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

来源:https://stackoverflow.com/a/9943871/4154421