I have a .NET Core program that uses the MySqlConnection class. My Database is a ClearDB Database that is stored in Azure.
When I launch the program it is working like it should. But when I wait for like 10 minuts doing nothing, it wont connect to the database anymore(Timeout?). Restarting the program and it works again.
When looking at the connections on the ClearDB webpage it isn't closing when I close it in my program. After 10 minuts or so it closes automaticly, as I see in ClearDB webpage. But with the program still running it wont connect to the database anymore. Restarting program is only solution.
Code for now looks something like this:
private static async Task<uint> getDeviceId(string macAddress)
{
using (var connection = new MySqlConnection(ConnectionString))
{
uint returnvalue = 0;
var cmd = connection.CreateCommand() as MySqlCommand;
cmd.CommandText = #"SELECT id FROM devices WHERE mac = '" + macAddress + "'";
connection.Open();
Console.WriteLine(connection.State);
DbDataReader reader = await cmd.ExecuteReaderAsync();
using (reader)
{
while (await reader.ReadAsync())
{
returnvalue = await reader.GetFieldValueAsync<uint>(0);
}
}
reader.Dispose();
cmd.Dispose();
return returnvalue;
}
}
I have tried the following:
Using statement
Close/dispose connection,reader and command
Pooling=false in connectionstring
But none of them works. Somebody got an idea?
Assuming MySql provider is like the MSSQL provider, it does not actually close the connection in the database, it just releases it back to the pool.
You do not want to disable pooling, you will kill efficiency.
This is by design, and what you want.
The using statement from the code snippet should close your connections. However, I'm not sure how that interacts with async, or how ClearDB differs from normal MySql. Given the issues in the question and that lack of clarity, you might try this, just to see if it helps:
private static async Task<uint> getDeviceId(string macAddress)
{
uint returnvalue = 0;
MySqlConnection connection;
try
{
connection = new MySqlConnection(ConnectionString);
var cmd = connection.CreateCommand() as MySqlCommand;
//Don't EVER(!) use string concatenation like that in a query!
cmd.CommandText = #"SELECT id FROM devices WHERE mac = #macAddress";
cmd.Parameters.Add("#macAddress", MySqlDbType.VarChar, 18).Value = macAddress;
connection.Open();
Console.WriteLine(connection.State);
DbDataReader reader = await cmd.ExecuteReaderAsync();
using (reader)
{
while (await reader.ReadAsync())
{
returnvalue = await reader.GetFieldValueAsync<uint>(0);
}
}
reader.Dispose();
cmd.Dispose();
}
finally
{
connection.Close();
connection.Dispose();
}
return returnvalue;
}
A using block basically just re-writes your code as try/finally anyway, so doing this step by-hand can sometimes make debugging easier (you can log where it hits the .Close() call).
If this does resolve the problem, I wouldn't stop there, but rather start from there and see just how close to "normal" code you can get. I'm also concerned here that you have disabled connection pooling, and that this method is static.
Related
I am using C# in Visual Studio 2019, with Xamarin.Forms, and SQl in SSMS 2018 and have the below code (where [] is used to replace unneccessary information)
try
{
using(SqlConnection connection = new SqlConnection())
{
connection.ConnectionString = "Server=[ServerName]; Database=[DatabaseName]; User Id= [UserID]; Password=[Password]";
connection.Open();
SqlCommand command = new SqlCommand("SELECT * from [TableName]", connection);
[Does stuff here]
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex)
}
When I run this, it hangs indefinitely at connection.Open(). Debug mode continues to run and appears to move on from Connection.Open(), but never reaches the next line.
I have attempted this with different versions of the ConnectionString, using different databases and with Trusted_Connection=true instead of specifiying the username and password but they have made no difference. Adding Connection Timeout = 5 to the connectionString has no effect.
I believe it is probably an issue with my settings in SQL but as I am a novice with this I have no idea where to start and the similar forums posts I have checked have been given answers along the lines of Connection Timeout (Connection.open for hangs indefinitely, no exception is thrown) or never got answered.
Any advice would be greatly appreciated.
Can you log into SSMS with the credentials that are in the connection string?
Otherwise I've had luck making sure the connection isn't already open or broken first:
if (connection.State == ConnectionState.Closed || connection.State == ConnectionState.Broken)
{
connection.Open();
}
Can you try code changing line as per below -
connection.ConnectionString = "Data Source=[ServerName]; Initial Catalog=[DatabaseName]; Integrated Security=SSPI;"
A workaround to this problem is to pass in a cancellation token instance as shown below,
public async Task<IEnumerable<Toy>> ShowToybox(CancellationToken t)
{
// notice I turned this into an async operation.
// Reason is to let this operation to find its way out if something happens
var connString = "Server=xyz; Connection Timeout=250";
//Timeout might not happen, if that is not the case see below..
using(SqlConnection connection = new SqlConnection(connString))
{
if ( t.IsCancellationRequested) {
t.ThrowIfCancellationRequested();
}
// await query here. To fetch records from the toybox table
return matches;
}
Main issue is that you cannot trust connection.State
To get this working, code that consumes this method should expect something might go wrong.
class Program
{
static void Main()
{
var box = new ToxBox(); //it has method shown above
var s = new CancellationTokenSource();
s.CancelAfter(400); //it prevents method from hanging
var task = Task.Run(() = box.ShowToybox(s.Token));
try
{
task.Wait(s.Token);
var myToys = task.Result();
Console.WriteLine($"I have {myToys.Count()} toys");
}
catch (Exception e)
{
Console.WriteLine("Something happened!");
}
finally
{
s.Dispose(); //this is important
}
}
}
See https://learn.microsoft.com/en-us/dotnet/standard/threading/cancellation-in-managed-threads
I have a C# project that is working with TCP socket in an asynchronous way.
Every request comes from client and ask question from SQL Server stored procedure, opens and closes a SQL connection after ending of question.
I've used this code:
using (var con = new SqlConnection(setting.ConnectionString))
{
try
{
//some codes (edited)
SqlCommand command = new SqlCommand(con);
command.CommandText = "procedurename1";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#name", sb.ToString()));
SqlDataAdapter adapter = new SqlDataAdapter(command);
try
{
adapter.Fill(dataSet);
}
catch (Exception ex)
{
con.Close();
con.Dispose();
throw ex;
}
finally {
con.Close();
con.Dispose();
}
}
catch(Exception ex)
{}
finally
{
con.close();
con.dispose();
}
}
I've used
netstat -a -n | find /c "1433"
to count SQL connections open and close.
Problem is SQL connections count increases and it rarely decreases and count down.
Main problem, is when my program works under lots of requests about 30 minutes, I get
SqlCommand timeout error (default 30 seconds passed)
and after restarting my C# program, the SqlCommand timeout will be gone.
Is this a problem of my program or SQL Server side?
Remember it always calls a stored procedure in SQL Server, not executing query
directly.
main method:
public void main()
{
Task.Factory.StartNew(() =>
{
allDone.Reset();
mySocket.AcceptAsync(e);
allDone.WaitOne();
});
}
public void e_Completed(object sender, SocketAsyncEventArgs e)
{
var socket = (Socket)sender;
ThreadPool.QueueUserWorkItem(HandleTcpRequest, e.AcceptSocket);
e.AcceptSocket = null;
socket.AcceptAsync(e);
}
public void HandleTcpRequest(object state)
{
//do some code and connection to SQL server
DLL.Request httprequest = new DLL.Request(dataSet.Tables[0], fileDt);
DLL.IHttpContext _context = new DLL.HttpContext(httprequest);
_context.GetResults();
}
Main problem, is when my program works under lots of requests about 30 minutes,
To isolate the root problem of the time-out, I suggest testing the sql query of the stored procedure independent of TCP socket calls for 30 minutes
and log the time-out exception details for inspection
Run the following query within 30 minutes to simulate your working environment:
public void RunQuery()
{
using (var con = new SqlConnection(setting.ConnectionString))
{
try
{
//some codes
}
catch(SqlException ex)
{
//test for timeout
if (ex.Number == -2) {
Console.WriteLine ("Timeout occurred");
// log ex details for more inspection
}
}
}
}
Read How to handle the CommandTimeout properly?
As you use async calls, I suggest you to try to use Asynchronous Database Calls With Task-based Asynchronous Programming Model (TAP)
I'm going to take a long-shot based on the way the limited Sql-related code we can see is written since we can't see "//some codes".
I'm going to guess that some of the disposable things like SqlCommand, DataReader, SqlDataAdapter, TransactionScope, etc are not in 'using' blocks, so are holding resources open on the database.
It may also be worth raising the possibility that this kind of problem could be in the code shown in the question or any other program accessing that database, including your own applications and SSMS (e.g. if a developer has an uncommitted transaction running in a window).
P.S. I would suggest deleting everything in the using block except the "//some codes" part.
UPDATE after more code was added
Here is your code after correction. this will ensure that the resources are disposed, which will prevent the leaking resources that are probably causing your problem.
using (var con = new SqlConnection(setting.ConnectionString))
{
//some codes (edited)
using (SqlCommand command = new SqlCommand(con))
{
command.CommandText = "procedurename1";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter("#name", sb.ToString()));
using (var adapter = new SqlDataAdapter(command))
{
adapter.Fill(dataSet);
}
}
}
P.S. don't ever write "throw ex;" from inside a catch ever again. It causes the stack trace to be lost - just use "throw;".
I have a problem. I'm writing window form application in c#.net and connect to SQL Server on Local Network.
if network disconnected my program is not responding. I mean it tries to select data from sql server but network is disconnected. How to catch this error? Thanks in advance.
Check the documentation for timing out MSDN
Here's their example code
using System;
using System.Data.SqlClient;
///
public class A {
///
public static void Main() {
string connectionString = "";
// Wait for 5 second delay in the command
string queryString = "waitfor delay '00:00:05'";
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
SqlCommand command = new SqlCommand(queryString, connection);
// Setting command timeout to 1 second
command.CommandTimeout = 1;
try {
command.ExecuteNonQuery();
}
catch (SqlException e) {
Console.WriteLine("Got expected SqlException due to command timeout ");
Console.WriteLine(e);
}
}
}
}
Notice the line
command.CommandTimeout = 1;
Definitely wrap your sql code under the 'using' too, as it will deallocate resources automatically for you.
You basically need to check for the Open Connection First!
SqlConnection con = new SqlConnection(Connection_string); //specify your connection string such as Server database etc ...
if (con.State == System.Data.ConnectionState.Open)
//statements
And you can make an event to Notify that the connection has been closed !
I'm having a serious issue with my app. It builds a lot of MySql connections and then it's causing a crash.
I build every method like that:
MySqlConnection connect = new MySqlConnection(
local_connection_string
); //this is global variable.
protected void sample()
{
try
{
connect.Open();
MySqlCommand query = new MySqlCommand(
"here some mysql command"
, connect);
query.ExecuteNonQuery();
}
catch
{
}
finally
{
connect.Dispose();
connect.Close();
}
}
For some reason it's not closing any of these connections and when I keep refreshing it builds connections on the server, once limit is hit app is crashing. All connections are closed when app is shut down.
try this:
using(MySqlConnection conn = new MySqlConnetion(local_connection_string)
{
conn.open();
MySqlCommand query = new MySqlCommand(
"here some mysql command"
, connect);
query.ExecuteNonQuery();
}
using(resource){}: right way for IDisposable resource usage
probably need to add: Application.ApplicationExit event with MySqlConnection.ClearAllPools()
To ensure that connections are always closed, open the connection inside of a using block, as shown in the following code fragment. Doing so ensures that the connection is automatically closed when the code exits the block.
using (MySqlConnection connection = new MySqlConnection(connectionString))
{
connection.Open();
// Do work here; connection closed on following line.
}
MySQL counter part uses Connection pooling and does not close when you call close instead it puts it in the connection pool!
Make sure you First Close then Dispose the Reader, Command, and Connection object!
You can use ConnectionString Parameter "Pooling=false" or the static methods MySqlConnection.ClearPool(connection) and MySqlConnection.ClearAllPools()
and Using keyword is the right way to go with this kind of Scenario.
Just close first the connection , before calling the dispose...
finally
{
connect.Close();
connect.Dispose();
}
I built a parser that takes data stored in an xml file and sends it into a Microsoft Access database using linq-to-sql. I have the sql insert commands and they work... until they don't.
It's odd, I have each SQL command run (I keep them in a List and execute each command one at a time) and the first 40 or so run fine until they start hitting "unspecified error"s. The thing is, if I swallow the exception and instead have the exception catcher keep retrying, after a few seconds, they start working again. This means it's not an error of the SQL query itself (or at least how it's written).
This pattern repeats (there are thousands of inserts) many times. If I do normal exception handling, the program will just skip a few records while the error happens and keep inserting when whatever causes it temporarily goes away. if I let it run it's course, it inserts some records, skips some, inserts, skips, repeat and eventually inserts less than 2/3 of the records.
Is there any reason why my computer would only run 40 or so Inserts and then refuse to run more for a random but short interval?
I'm at a loss on what could be causing this.
The application is natively run; it does not use any server/web communication and all I found when looking for "unspecified error" pointed me to occurrences in ADO.NET applications.
Here's the code the error happens in:
public static string insertQuery(string sql)
{
string connetionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Documents and Settings\Owner\Desktop\Arbeit\TrademarkParserproject1\TrademarkParserproject\bin\x86\Debug\Database.accdb";
OleDbConnection connection;
OleDbDataAdapter oledbAdapter = new OleDbDataAdapter();
connection = new OleDbConnection(connetionString);
string success = "false";
try
{
connection.Open();
oledbAdapter.InsertCommand = new OleDbCommand(sql, connection);
oledbAdapter.InsertCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
success = ex.ToString();
return success;
}
success = "true";
return success;
}
Note, I have the application running in X86 mode to avoid errors with the ACE.OLEDB.12.0 adapter.
One thing that stands out, is you never close/dispose your SqlConnection. OleDbDataAdapter is also disposable and should be disposed. A 'using' statement is a convenient construct here:
public static string insertQuery(string sql)
{
string connetionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Documents and Settings\Owner\Desktop\Arbeit\TrademarkParserproject1\TrademarkParserproject\bin\x86\Debug\Database.accdb";
using(var oledbAdapter = new OleDbDataAdapter())
using(var connection = new OleDbConnection(connetionString))
{
string success = "false";
try
{
connection.Open();
oledbAdapter.InsertCommand = new OleDbCommand(sql, connection);
oledbAdapter.InsertCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
success = ex.ToString();
return success;
}
success = "true";
return success;
}
}