Connection.open for hangs indefinitely, no exception is thrown - c#

When I try to do the following code, the program hangs indefinitely. I don't know why and there seems to be other unanswered topics on the matter. Although, if the IP\website cannot be reached, then it works as intended.
private void DoStuff()
{
string connectionString = "Data Source=www.google.com;Connection Timeout=5";
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open(); //Hangs here indefinitely
Console.WriteLine("Test");
}
}
For example, if I set the connection string to
connectionString = "Data Source=www.nonexistentsite.com;Connection Timeout=5";
then it will throw an exception. How do I get it to throw an exception for an active site? ... Also google is just for testing purposes, obviously.
EDIT :
If I try to connect to an unreachable server name or IP address I WILL get this exception...
A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
UPDATE :
After letting the program run for quite a while, it usually times out finally after 3-5 minutes and gives me the error I posted above. How can I get it to timeout quicker?

If you have set an FQDN (Fully Qualified Domain Name) for your Data Source such as example.com and the DNS server is unable to resolve this FQDN for a long time it is pretty obvious that your request will hang out. Make sure that the machine from which you are running your application can reach the SQL server and resolve it without any issues. Also you probably want to make sure that there is no firewall that might be blocking the request.
Another possible cause for those symptoms is if you have exhausted the connection pool of ADO.NET. This could happen if you have many slow SQL queries running in parallel, each of them taking a physical connection to the database. There is a limit in the number of available connections on this pool and when this limit is reached the next call to connection.Open() might wait for an available connection to be returned to the pool.
Remark: you might also need to specify in your connection string how you want to authenticate against the SQL server. Checkout connectionstrings.com for more examples.
All this is to say that there is absolutely nothing wrong in the C# code you have posted in your question. It looks more like a network related problem that you could bring to the attention of your network administrators.

To get the connection to exit after a specified amount of time without success, you can use the Connection Timeout parameter in the connection string. The number you specify is in seconds, so for example, Connection Timeout=240 is equal to 240 seconds\60 seconds = 4 minutes.
Sample connection string:
<add name="MyConnectionString"
connectionString="
Data Source=MyServer\MSSQL2017;
Initial Catalog=MyDatabase;
Integrated Security=True;
Connection Timeout=10;"/>
In the above connection string, the Open() command will timeout after 10 seconds.

Related

.NET 6 C# Getting timeout attempting to connect to Snowflake database

Every time I try to connect to a snowflake database in .NET 6 using the Snowflake.Data NuGet package, I get a timeout after 120 seconds. I've tried it with all correct credentials in the connection string, as well as all incorrect credentials. No matter what the response is the same:
[2022-06-26T21:05:06.742Z] Snowflake.Data.Client.SnowflakeDbException (0x80004005): Error: Snowflake Internal Error: Unable to connect SqlState: 08006, VendorCode: 270001, QueryId:
[2022-06-26T21:05:06.743Z] ---> System.AggregateException: One or more errors occurred. (Error: Request reach its timeout. SqlState: , VendorCode: 270007, QueryId: )
My code setup looks like this to connect:
using (var conn = new SnowflakeDbConnection())
{
conn.ConnectionString = #"
ACCOUNT=<account>;
USER=<user>;
PASSWORD=<password>;
ROLE=<role>;
DB=<db>;
WAREHOUSE=<warehouse>";
_log.Information("Attempting connection to Snowflake...");
await conn.OpenAsync();
...
Every time after attempting to open the connection it hangs for 120 seconds then produces the above error. I've tried async and non-async as well as a bunch of different connection string properties. I also verified I was able to establish an outbound connection to another database with a regular SqlConnection and that worked with no issues. Not sure what could be going wrong.
Also ran the Snowcd connection diagnostic tool as descripted in the docs, results were all passing:
After much trial and error, adding the specific HOST value to the connection string was what fixed it for me. Specifying the full account with region for the ACCOUNT value did not work. Only when done under HOST. Although the GitHub documentation states that HOST is not required, specifying it with the region is the only thing that prevented timeouts on my end.

Adding Keepalive option to MySQL connection causes error "Unable to connect to any of the specified MySQL hosts"

I am working on a project where a thread is run and opens a permanent database connection. The reason for this, is potentially as the project grows it could receive more and more requests so it's more efficient to keep the database open and usable instead of opening and closing the database.
Basically what the thread does is look for events in a queue, and if there is an event it starts working on the database to store and process the event. At its peak this thread could receive 50,000-100,000 requests a day potentially a lot more, as more and more users (hopefully) use the service.
However, because it's new, there are times where this thread doesn't have anything to do, so I end up hitting the exception "The connection must be valid and open" and I believe this is because the connection to the database is automatically dropped over 8 hours of inactivity. At the moment this can happen so I am trying to add a Keepalive option to the connection so this doesn't happen but for some reason, as soon as I add this, I then get the error "Unable to connect to any of the specified MySQL hosts".
I am using a MysqlConnectionStringBuilder as follows:
MySqlConnectionStringBuilder connectionBuilder = new MySqlConnectionStringBuilder();
connectionBuilder.Server = server;
connectionBuilder.UserID = username;
connectionBuilder.Password = password;
connectionBuilder.Port = 3306;
//Open the connection
MySqlConnection conn = new MySqlConnection(connectionBuilder.ConnectionString);
conn.Open();
This above works perfectly fine until I add the following:
connectionBuilder.Keepalive = 60;
When the above line is added is when I then get the error.
I am using a TCP connection as it's a remote connection from my Dev PC to a dev server - is there a setting on the server to enable this? as everything I've found on Google this option is all that's required.

Issue connect to SQL Server 2000 from C#

I am using a Winforms C#, .Net Framework 4.0 application and I'm trying to connect to SQL Server 2000 using Data.SqlClient. Database and app are running on the same server machine.
Before, I ran app on 2 other servers successfully.
My connection string in config is:
ConnectionString="Data Source=xyz;Initial Catalog=xyz;Integrated Security=True;"
but a 3rd server causes an error:
Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=3998; handshake=0; [Login] initialization=0; authentication=0; [Post-Login] complete=10000; "
Then, I changed the connection string to
ConnectionString="Data Source=xyz;Initial Catalog=xyz;Integrated Security=True;Connection Timeout=30;"
and I get a new error
A transport-level error has occurred during SSPI handshake. (provider: Named Pipes Provider, error: 0 - The pipe has been ended.)
Update: I tried using the udl file to create the connection string and put it into the config file but there is still error
So what am I missing here ?
Thanks in advance.
Update: I fixed this issue when replace sqlclient by OLEDB lib
ConnectionString="Data Source=xyz;Initial Catalog=xyz;Integrated Security=True;"
This may be correct try to close your connection after you open
I think you are not missing anything. Your connection string looks good to me.
ConnectionString="Data Source=xyz;Initial Catalog=xyz;Integrated Security=True;
May be due to any reason the connection was placed using Named Pipes instead of Shared Memory. Shared Memory is the default option for local SQL connection so SqlClient could not recognize the connection was local, and placed through Named Pipes over TCP. Result is connection was refused or not connected.
I am not sure but please check you server name, it should be qualified domain name or IP address. If you specify it by the hostname or "." or "(local)", SqlClient should recognize the local connection, and you should not see the error.
I've just been through this problem and nothing I found anywhere helped, so I thought I'd share the solution that helped me.
Turns out my client had used "username#domain.com" as their login instead of just "username". Looks like there is some functionality internal to excel that tries to authenticate the user via that domain, and thus, the connection times out without a response. Don't create logins with "#domain.com" in SQL Server.
Hope this helps someone in future.

connecting to mirrored databases after failover

I have two mirrored SQL Servers (A and B for example).
I wrote a simple C# program (connect via SqlConnection), which insert rows into DB. When I make failover on server A, the program throws exception, then I try reconnect, and get exception by timeout (**A connection was successfully established with the server, but then an error occurred during the pre-login handshake. (provider: SSL Provider, error: 0**).
When I restart the app, the connection is successfully established (to server B). Next, I make failover on B server, and program throws exception, then I try to reconnect, and its work - connection to A witout restarting program.
My connection string:
Data Source=SERVER_A;Failover Partner=SERVER_B;Initial Catalog=TEST_DB;persist security info=True;user id=USER_LOGIN;password=USER_PASS;Connection Timeout=60;
I also try to set big timeout (60 seconds), and try to clear All sqlconnection pools, clear single pool by connection, but it is not working.
Interesting fact: if I use domain login and password, all works fine!
(user SID are same)
Hard to tell what your exact problem is. Perhaps it's that failovers aren't instant, and can't transfer query state - see https://dba.stackexchange.com/questions/27528/can-availability-groups-provide-seamless-failover-with-no-query-failures. If your application immediately retries the query the failover node may therefore still be in the process of taking over and therefore not ready to accept connections.

Solving a timeout error for SQL query

I am getting this error:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
I know there are already guides out there to help solve this but they are not working for me. What am I missing or where should I add the code to these SQL statements in my C# program:
String sql = project1.Properties.Resources.myQueryData;
SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql,
"Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
DataSet lPlanViewData = new DataSet();
sqlClearQuestDefects.Fill(lPlanViewData, "PlanViewData");
I am getting the timeout error at this line:
SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql,
"Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
SqlDataAdapter adp = new SqlDataAdapter();
adp.SelectCommand.CommandTimeout = 0; // Set the Time out on the Command Object
You're trying to connect to a SQL Server, and it is taking longer than ADO.NET is willing to wait.
Try connecting to the same server, using the same username and password, using SQL Server Management Studio. If you get the same error, there is either something wrong with your connection string, the server you specify is not running, or you can't get to the server across the network from where you are (maybe you're on a public IP address trying to get in to an internal server name). I can't think of a scenario in which you'd enter the exact same server and credentials into SSMS and connect, then do the same in ADO.NET and fail.
If you're on a slow network, you can try increasing the timeout value. However, if a connection is going to happen at all, it should happen pretty quickly.
Take a look at both your SQL Native Client settings, and the SQL Server settings on the server. There is a section for allowed protocols; SQL can connect using a variety of protocols. Usually, you want TCP/IP for a server on the network, and Named Pipes for a server running on your own computer.
EDIT FROM YOUR COMMENT: Oh, that's normal; happens all the time. From time to time on a TCP network, packets "collide", or are "lost" in transmission. It's a known weakness of packet-switching technologies, which is managed by the TCP protocol itself in most cases. One case in which it isn't easily detected is when the initial request for a connection is lost in the shuffle. In that case, the server doesn't know there was a request, and the client didn't know their request wasn't received. So, all the client can do is give up.
To make your program more robust, all you have to do is expect a failure or two, and simply re-try your request. Here's a basic algorithm to do that:
SqlDataAdapter sqlClearQuestDefects;
short retries = 0;
while(true)
{
try
{
sqlClearQuestDefects = new SqlDataAdapter(sql, "Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
break;
}
catch(Exception)
{
retries++;
//will try a total of three times before giving up
if(retries >2) throw;
}
}
Since the exact command to increase connection time out wasn't mentioned in the other answers (of yet)- if you do determine a need to increase your connection time out, you would do so in your connection string as follows:
Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa; Connection Timeout=120
Where 120 = 120 seconds. Default is 20 or 30 as I recall.
This is probably a connection issue with your database, for example if you had the following connection string:
"Data Source=MyDatabaseServer...
Then you need to make sure that:
The machine MyDatabaseServer is connected to the network and is accessible from the machine you are running your application from (under the name "MyDatabaseServer")
The database server is running on MyDatabaseServer
The database server on MyDatabaseServer is configured to accept connections from remote machines
The firewall settings both on the local machine and MyDatabaseServer are correctly set up to allow SQL Server connections through
Your username / password etc... are correct
You can also try connecting to the given database instance using SQL Server Management Studio from the client machine as a diagnosis step.
There are plenty of articles that address SQL Server connectivity issues - do a Google search for the specific error message that comes up or failing that as a specific question on Server Fault
Faced this problem recently and found the resolution that worked for me.
By the way, setting Timeout = 0 helped to avoid the exception, but the execution time was unreasonable, while manual execution of the store procedure took a few seconds.
Bottom line:
I added SET IMPLICIT_TRANSACTIONS OFF to the stored procedure that is used to fill the data set.
From MSDN:
The SQL Server Native Client OLE DB Provider for SQL Server and the
SQL Server Native Client ODBC driver automatically set
IMPLICIT_TRANSACTIONS to OFF when connecting. SET
IMPLICIT_TRANSACTIONS defaults to OFF for connections with the
SQLClient managed provider, and for SOAP requests received through
HTTP endpoints.
[...]
When SET ANSI_DEFAULTS is ON, SET IMPLICIT_TRANSACTIONS is ON.
So I believe that in my case defaults weren't as required. (I couldn't check that. Don't have enough privileges on SQL server). But adding this line to my SP solved the problem.
IMPORTANT: In my case I didn't need the transaction, so I had no problem to cancel the implicit transaction setting. If in your case transaction is a must you, probably, shouldn't use this solution.

Categories

Resources