写了一个函数,想放在线程中启动运行,用来检测数据库服务(本地或远程)是否处于可连接状态。
自己的思路是,在线程中创建一个SqlConnection对象,不停的Open()来检测其State为Open或Closed。1)这样做首先是产生很多异常:
我把sql数据库服务关闭时,产生异常“在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)”;
把数据库服务打开时,产生异常“连接未关闭。 连接的当前状态为打开。”;2)其次sql数据库服务从关闭到打开的时候,可以看到我程序的状态栏从“断开”变成了“连通”;
而当我把数据库服务停掉的时候,程序状态栏却始终保持“连通”不变。不知道是怎么回事。或者有更好的做法?我的目的只是要检测数据库是否处于可连接状态,即网络不通、数据库服务没启动,等等状态统统都检测为“断开”;而当检测为“连通”时,必须是可以通过conn.Open()打开数据库连接。
using (SqlConnection conn = new SqlConnection(Config.SQL_CONN_STR))
{
while (true)
{
try
{
conn.Open();
}
catch (Exception ex)
{
if (conn.State == ConnectionState.Closed)
{
//把我的程序的状态栏的Label设置为断开
sspsl_ConnState.Text = "断开";
}
else if (conn.State == ConnectionState.Open)
{
sspsl_ConnState.Text = "连通";
conn.Close();
}
//下面三行是我自己写的异常记录日志,下面会把日志记录贴出来
StackTrace st = new StackTrace(new StackFrame(true));
StackFrame sf = st.GetFrame(0);
Tool.WriteLog(true , ex , st , sf);
}
Thread.Sleep(1000);
}
}

解决方案 »

  1.   

    这是我自己记录的异常日志,这里异常的变化就是我在监测程序开启的时候,打开了数据库服务导致的。
    而此后我再关闭数据库服务,异常却不会变回去-------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
    Time :10:56:20.6562500
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
    Time :10:56:21.7187500
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
    Time :10:56:22.7656250
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
    Time :10:56:23.7656250
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 在建立与服务器的连接时出错。在连接到 SQL Server 2005 时,在默认的设置下 SQL Server 不允许进行远程连接可能会导致此失败。 (provider: 命名管道提供程序, error: 40 - 无法打开到 SQL Server 的连接)
    Time :10:56:24.7812500
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:27.5000000
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:29.5156250
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:31.5156250
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:33.5156250
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:35.5312500
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:37.5312500
    -------------------------
    Location : UIL.Form_Main.GetDbConnectionState | 178
    Message : 连接未关闭。 连接的当前状态为打开。
    Time :10:56:39.5312500
      

  2.   

    我补充一下吧,可能我之前表达的不清楚:我之前是用 SqlConnection.Open() 和 SqlConnection.State 这两个方法跟属性来组合判断是否能连接;但是.Open()方法本身在不能连接的状态下(比如数据库服务没启动,网络有问题)就会报错,所以我希望能在使用Open()之前就判断是否可连接
      

  3.   


    SqlConnection.Open是怎么实现的?  
    原理上讲就是 sqlserver 服务的 tcp port 通道建立,如果失败报错
    你非要自己写个tcp port通信测试,有这必要么?
      

  4.   


    对的,我就是这个意思,这样不就可以避免 .OPen报错然后程序异常退出么~
      

  5.   

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading;namespace MyProgram.UIL
    {
    public class Service
    {
    public static void StartMSSQLSERVER()

    ServiceController sc = new ServiceController("MSSQLSERVER");
    switch (sc.Status)

    case ServiceControllerStatus.Stopped:
    sc.Start();
    break;
    case ServiceControllerStatus.Paused:
    sc.Continue();
    break;
    case ServiceControllerStatus.StartPending:
    break;
    default:
    break;
    }
    do
    {
    sc.Refresh();
    Thread.Sleep(1000);
    } while (!sc.Status.Equals(ServiceControllerStatus.Running));
    }
    }
    }
      

  6.   

    上面的代码用来侦测本地机器上Sql服务是否开启
    至于远程数据库连接如6#所说,没有必要去特别侦测
    如果是害怕程序崩溃,添加一个try-catch就好了
      

  7.   

    还是不明白。
    我这样写好像有问题:
    当之前连接正常,然后我把服务关闭后,还是提示连接正常,open不出异常,郁闷了。请大侠指导
    public static bool ChkOCDBLink(string connString)
            {
                bool result = true;            OracleConnection conn = null;
                try
                {
                    conn = new OracleConnection(connString);
                    conn.Open();
                    if (conn.State == ConnectionState.Open)
                    {
                        result = true;
                        conn.Close();
                    }
                    else
                    {
                        result = false;
                    }
                }
                catch (OracleException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    result = false;
                }
                finally
                {
                    if (conn != null)
                    {
                        conn.Dispose();
                        conn = null;
                    }
                }
                return result;
            }
      

  8.   

    据说 在 OPEN 之前先PING 一下可能更有效果?
    但我 PING 主机名时会异常,只能 PING IP 地址.