简体   繁体   中英

Changing Connection Timeout for SQL Server connection has no effect

I'm trying to set the timeout for making a connection to an SQL server in C# using the following code:

var sscsb = new SqlConnectionStringBuilder(sConn);
sscsb.ConnectTimeout = 10;                 

SqlConnection connection = new SqlConnection(sscsb.ConnectionString);

using (connection)
{                       
    connection.Open();
    connection.Close();
    return (true);
}

but 30 seconds elapses before the connection.Open() statement throws an error. How can I set the connection timeout to a shorter value?

I got this problem when I tried to connect to an invalid server name, or when the network connection to a valid server was down. In those cases the timeout value was ignored. It seems that the timeout does not apply to the attempt to validate the server and send the connection request. It seems to only apply to how long it will wait for a connection once a valid server has been found and the request made.

I used a timer-based solution although I can't seem to find it and it was definitely a workaround. This threading-based solution seems like the way to go.

I've investigated this problem once and came to this conclusion: The connection timeout specified in the connection string or at the connection means: if a sql server is listening, wait x seconds for it to accept the connection request. If no server is listening at the port (eg the sql server isn't running) the default socket connection timeout is used, which is 30 seconds by default. A workaround is to manually open a socket connection to the sql server with a custom timeout to check if it is running.

Code below tests for connection and being able to run a query on connection. Query needs to reference a small table in target D/B:

 /// <summary>
    ///  Return true if successful SQL connection 
    /// </summary>
    /// <param name="conn"></param>
    /// <param name="timeout">timeout in msec</param>
    /// <returns></returns>
    public static bool QuickSQLConnectionTest(SqlConnection conn, int timeout)
    {
        // We'll use a Stopwatch here for simplicity. A comparison to a stored DateTime.Now value could also be used
        Stopwatch sw = new Stopwatch();
        bool connectSuccess = false;

        // Try to open the connection, if anything goes wrong, make sure we set connectSuccess = false
        Thread t = new Thread(delegate()
        {
            try
            {
                sw.Start();
                conn.Open();
                SqlCommand cmd = new SqlCommand("Select Count(*) from Configuration", conn);
                cmd.CommandTimeout = timeout/1000; // set command timeout to same as stopwatch period
                cmd.ExecuteScalar();
                connectSuccess = true;
            }
            catch (Exception Ex)
            {
            }
        });


        // Make sure it's marked as a background thread so it'll get cleaned up automatically
        t.IsBackground = true;
        t.Start();

        // Keep trying to join the thread until we either succeed or the timeout value has been exceeded
        while (timeout > sw.ElapsedMilliseconds)
            if (t.Join(1))
                break;

        // If we didn't connect successfully
        if (!connectSuccess)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM