这个是WINFORM程序,主要就是测试连接字符串能不能用的问题。 
conStr是个参数可以传递不同的要测试的连接字符串。 
但是当IP错误,或者数据库名称错误的时候,抓取异常所产生的时间太长,而且抓取异常情况的时候程序假死。然而用户名和密码出错的时候异常等待时间却很短。 
请各位大哥给指点以下,能不能缩短抛出异常的时间。 100分悬赏
string conStr="server=.;database=kk;uid=sa;pwd=;Connection Timeout=5"; 
using(SqlConnection con=new SqlConnection(conStr)) 

try{ 
con.open(); 

catch(Exception ee) 

MessageBox.Show(ee.Message); 

}

解决方案 »

  1.   

    你要明白当IP错误时超时时间,不是数据库超时时间,而是 网络超时时间
    网络超时时间,在本地计算机的注册表中设置
    你可以用Windows优化大师来设置它
      

  2.   

    connection.connectiontimeout,设置一下应该就可以,单位是秒
      

  3.   

    是 网络超时时间,并不是数据库反应时间。这个不建议通过修改 Windows 设置(如修改注册表等),因为当网络环境不好时,可能会连接延时一小会儿才能连接,如果你修改 Windows 网络超时时间,可能会有很多可能连接上的时候也被视为连接不上了。如:网络超时时间设为 5秒,实际网络状态一般,经过7秒可以连接成功,这种情况就会直接连不上了,所以不建议修改这些值。
      

  4.   

    SqlConnection con = new SqlConnection("server=.;database=master;uid=sa;pwd=;");
    con.ConnectionTimeout = 180;
    SqlCommand cmd = new SqlCommand();
    或用Thread.Sleep()延迟
      

  5.   

    网络超时时间,并不是数据库反应时间。 这个不建议通过修改 Windows 设置(如修改注册表等),因为当网络环境不好时,可能会连接延时一小会儿才能连接,如果你修改 Windows 网络超时时间,可能会有很多可能连接上的时候也被视为连接不上了。 如:网络超时时间设为 5秒,实际网络状态一般,经过7秒可以连接成功,这种情况就会直接连不上了,所以不建议修改这些值。 
      

  6.   

    人家都说了,就是要缩短反应时间,为什么不改?Windows默认的网络超时时间一般为30秒。通常在局域网内,10秒钟还连不上,就可以认为是网络故障了,还需要等30秒?
      

  7.   

    andywongz  你的建议很好,本人是个新手,能否劳累你用个代码的实现方法解决呢。当测试一个IP的时候没问题,异常时间也就是40秒僵硬。如果是批量测试就是40秒*N 等待时间是可想而知的,如果你有很好的解决办法,请详细说明下,在此感谢所有回答者。
      

  8.   

    补充说明 : IP可能会出现问题,同样的数据库名称也肯能出现问题。如果去PING IP可以解决这个IP的异常问题;但是,如果是数据库名称错写,误写,那么抛出异常僵硬的时间问题还是存在的。
      

  9.   

    你知道OSI的七层结构吧
    SQL语句,这已经是在应用层上了而你所要控制的网络超时,却在协议层那么你必须用一个能够控制协议层的东西我的建议是,若你不适用代码,那么用windows优化大师直接修改本地电脑的默认网络超时时间是比较好的办法如果你的客户端非常多,且你又无法控制客户电脑,那么我建议你首先用一个Socket语句去探测目标服务器,排除网络问题,然后再进行SQL连接。
    而在Socket里,你是可以控制超时时间的。至于.NET WINFORM的有关Socket知识,你在网上搜搜吧,太多了。
      

  10.   

    问你个问题,我是菜鸟,你的程序的第二行的 using什么意思啊? 经常在写程序前用using ***** 加载使用的命名空间,(不知道这么说对不对,using要么就是加载类库什么的)
    不知道在程序中的using什么意思,经常在msdn的例子上见到,就是不知道什么意思!!!借你的分问点问题吧,呵呵.别介意啊?我没分了!!
      

  11.   


    呵呵实际上我发这个帖子的时候已经知道 IP错误的解决办法了,我的补充说明中的 C#实现PING的原理就是用的SOCKET。问题就像ximi82878 前半句说的,异常是必然的,那我想的是用偶然的方法绕过必然性。简单点说能否有象C#实现PING原理一样绕过TRY CATCH捕捉“数据库名称”的异常,因为这个异常等待时间和IP发生错误是一样的异常级别(异常级别20),这个级别的异常等待时间都是很长的。
      

  12.   


    这个地界没有什么菜鸟,只有愿意学,和愿意学,还有愿意学习的人来的地方。
    关于这个USING 网上有很多介绍。http://baike.baidu.com/view/2114100.htm 百科上将的已经很完美了,如果没看懂就去MSDN上查查。
    如果用我这个代码段举例子,我只能说SQLCONNECTION 这个对象是被引用的,在这个USING里面他的生存期是存在的,如果程序走出了UISNG的范围,这个对象就自动被DISPOSE()掉了。
    要注意的就是USING中的生存对象,只能而且必须是继承IDISPOSE()接口的对象。
      

  13.   

    对不起哈,更正一下  是必须继承IDisposable接口。另外感谢所有回答。如果有更好的建议,我会给帖子加分,以回报您的付出。
      

  14.   

    我测试了下,用VS2005写的,在网络连接的情况下,如果数据库不存在,测试时间也是要45秒,是不是传说中的网络30秒+SqlConnection 15秒,设置的Connectioin Timeout 没起作用.下面是测试代码,测试项目在这里可以拿到http://www.brsbox.com/filebox/down/fc/b9efbe8f49d38cae2116c5dfef11cbbf
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using System.Net;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Net.NetworkInformation;
    using System.Data.SqlClient;namespace ConnectState
    {
        public partial class frmConnectTest : Form
        {
            [Flags]
            enum ConnectionState : int
            {
                INTERNET_CONNECTION_MODEM = 0x1,
                INTERNET_CONNECTION_LAN = 0x2,
                INTERNET_CONNECTION_PROXY = 0x4,
                INTERNET_RAS_INSTALLED = 0x10,
                INTERNET_CONNECTION_OFFLINE = 0x20,
                INTERNET_CONNECTION_CONFIGURED = 0x40
            }        [DllImport("wininet", CharSet = CharSet.Auto)]
            static extern bool InternetGetConnectedState(ref ConnectionState lpdwFlags, int dwReserved);        static bool IsOffline()
            {
                ConnectionState state = 0;
                InternetGetConnectedState(ref state, 0);
                if (((int)ConnectionState.INTERNET_CONNECTION_OFFLINE & (int)state) != 0)
                {
                    return true;
                }            return false;
            }        public frmConnectTest()
            {
                InitializeComponent();
            }        private void frmConnectTest_Load(object sender, EventArgs e)
            {        }        string _server = string.Empty;
            string _dbName = string.Empty;
            string _pwd = string.Empty;
            string _uid = string.Empty;        private void btnTest_Click(object sender, EventArgs e)
            {
                string host = string.Empty;
                bool isIPAddress  = false;
                IPAddress ip = null;            _server = txtServer.Text.Trim();
                _dbName = txtDB.Text.Trim();
                _uid = txtUid.Text.Trim();
                _pwd = txtPwd.Text.Trim();            if (_server.Length == 0 || _dbName.Length == 0 || _uid.Length == 0)
                {
                    MessageBox.Show("服务器、数据库、用户名不能为空,请填写.");
                    return;
                }            if (IsOffline())
                {               
                   if(MessageBox.Show("现在连接处于离线状态,继续测试吗?")== DialogResult.Cancel)
                    return;
                }            bool isLocal = Regex.IsMatch(_server.ToLower(), @"^.|(local)");
                isIPAddress = Regex.IsMatch(_server, @"^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$");            // 指定服务器是本机
                if (isLocal)
                {
                    try
                    {
                        ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format("Dns 错误:{0}", ex.Message));
                        return;
                    }
                }
                else if (isIPAddress) // 指定IP
                {
                    ip = IPAddress.Parse(_server);
                }
                else // 指定服务器名称
                {
                    try
                    {
                        ip = Dns.GetHostEntry(_server).AddressList[0];
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(string.Format("Dns 错误:{0}", ex.Message));
                        return;
                    }
                }            ParameterizedThreadStart thStart = new ParameterizedThreadStart(PingTest);
                thStart.BeginInvoke(ip, AsyncCallbackMethod, null);
                btnTest.Enabled = false;
                tssPro.Text = string.Format("正在测试与服务器{0}连接...", _server);
               
            }        private void AsyncCallbackMethod(IAsyncResult ar)
            {
               // 服务器ping测试通过后,检测Sql Server的连接
                if (success)
                {
                    DateTime? now = null;                tssPro.Text = string.Format("连接服务器{0}正常,正在测试与数据库{1}连接...", _server, _dbName);
                    string conStr = string.Format("server={0};database={1};uid={2};pwd={3};Connection Timeout=5;", _server, _dbName, _uid, _pwd);
                    SqlConnection con = new SqlConnection(conStr);
                    try
                    {
                        now = DateTime.Now;                   
                        con.Open();                   
                        con.Close();
                        tssPro.Text = "";
                        MessageBox.Show("测试连接成功");                }
                    catch (Exception ex)
                    {
                        TimeSpan ts = DateTime.Now.Subtract(now.Value);
                        MessageBox.Show(string.Format("无法连接数据库:{0}\n{1}\n耗时:{2}秒", _dbName,ex.Message,ts.Seconds));
                    }
                }
                else
                {
                    tssPro.Text = "";
                    MessageBox.Show(string.Format("找不到服务器:{0}",_server));              
                }
            }
            private bool success = false;        /// <summary>
            /// Ping 测试
            /// </summary>
            /// <param name="ipAddress"></param>
            private void PingTest(object ipAddress)
            {
                IPAddress ip = (IPAddress)ipAddress;
                
                PingOptions options = new PingOptions(128, true);            
                Ping ping = new Ping();            
                byte[] data = new byte[32];            //ping 4 次
                for (int i = 0; i < 4; i++)
                {
                    PingReply reply = ping.Send(ip, 1000, data, options);                if (reply != null)
                    {
                        switch (reply.Status)
                        {
                            case IPStatus.Success:
                                success = true;
                                break;
                            case IPStatus.TimedOut:                            
                                break;
                            default:                           
                                break;
                        }
                    }                
                }                   }    }
    }
      

  15.   


    啥也不说了,佩服! 这类的API函数没用过。学习了。再加100分。2天后结贴。
      

  16.   

    这个命题也许是无法解决的,但是iStarSoft给的建议非常好,回调函数可以解决窗体假死现象。
    再次谢谢所有回答者,结贴。