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