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 !
Related
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 .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.
I want to make use of the connection pooling so i could use the database without passing the MysqlConnection object to each class. I have a code like this:
Main.cs:
namespace batman
{
class Program
{
static void Main(string[] args)
{
using (MysqlConnection conn = new MysqlConnection("Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True"))
{
MonitorClass monitor = new MonitorClass();
monitor.Run();
}
//...
}
}
}
MonitorClass.cs:
namespace batman
{
public class MonitorClass
{
public void Run()
{
using (MySqlConnection conn = new MySqlConnection())
using (MySqlCommand cmd = conn.CreateCommand())
{
try
{
conn.Open();
cmd.CommandText = "SELECT id, package_type FROM package_registry WHERE finish_time <= #ftime";
cmd.Parameters.AddWithValue("#ftime", 0);
cmd.Prepare();
MySqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
int packageId = reader.GetInt32(0);
string packageType = reader.GetString(1);
Unirest.post("http://localhost/gears/ops/packagefinish")
.field("package", packageId)
.asStringAsync();
Console.WriteLine("[PackageMonitor] Package {0} ({1}) expired", packageId, packageType);
}
}
catch (MySqlException ex)
{
}
}
}
}
}
MonitorClass should take the connection from the connection pool.
But once I run my program it throws System.InvalidOperationException with
Additional information: Unable to connect to any of the specified MySQL hosts.
at:
cmd.Prepare();
Now, i think I'm doing something wrong, but I couldn't figure out what exactly.
Oracle docs says this
The Connector/Net supports connection pooling for better performance and scalability with database-intensive applications. This is enabled by default. You can turn it off or adjust its performance characteristics using the connection string options Pooling, Connection Reset, Connection Lifetime, Cache Server Properties, Max Pool Size and Min Pool Size. See Section 5.2, “Creating a Connector/Net Connection String” for further information.
Connection pooling works by keeping the native connection to the server live when the client disposes of a MySqlConnection. Subsequently, if a new MySqlConnection object is opened, it will be created from the connection pool, rather than creating a new native connection. This improves performance.
Well, there seem to be two different problems:
Connection is opened twice - first time in Main method and second time (independently) in Monitor class. This can be fixed by opening connection in monitor class only and passing connection string inside of it.
You never opened connection by invoking .Open() method.
Let's refactor your code keeping this in mind :
Main :
static void Main(string[] args)
{
var connStr = "Server=localhost;User=root;Database=test;Password=root;Min Pool Size=3;Max Pool Size=5;Pooling=True";
MonitorClass monitor = new MonitorClass(connStr);
monitor.Run();
//...
}
Monitor :
public class MonitorClass
{
private readonly string _connStr;
public MonitorClass(string connectionString)
{
this._connStr = connectionString;
}
public void Run()
{
using (MySqlConnection conn = new MySqlConnection(_connStr))
using (MySqlCommand cmd = conn.CreateCommand())
{
conn.Open();
...
}
}
}
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 have a loop that runs some ExecuteNonQuery commands. Occasionally it returns the error message:
ExecuteNonQuery requires an open and available connection. The connections
current state is closed.
Here is my code:
private void MyTimerEventHandler(object src, ElapsedEventArgs a)
{
sqlCon = new SqlConnection("server=" + appConfig.sqlServer + ";Trusted_Connection=yes;database=testdb;connection timeout=30;");
sqlCon.Open();
foreach (TagManager tm in tagManagerList)
{
foreach (Tag tag in tm.getTags())
{
SqlCommand insCmd = new SqlCommand("INSERT INTO tag_values (tag_id, value, time) Values (#tagId, #tagValue, #tagTime);", sqlCon);
insCmd.Parameters.Add(new SqlParameter("#tagId", tag.tagNameId));
insCmd.Parameters.Add(new SqlParameter("#tagValue", tag.value));
insCmd.Parameters.Add(new SqlParameter("#tagTime", tag.time));
insCmd.ExecuteNonQuery();
}
}
sqlCon.Close();
}
This code executes in the event handler of a Timer that runs every 15 seconds. The timer is kept alive by GC.KeepAlive() if that makes any difference.
Create a new connection object for each timer callback:
private void MyTimerEventHandler(object src, ElapsedEventArgs a)
{
SqlConnection sqlCon = new SqlConnection( [...]
It is normally a bad idea to reuse a connection. In your case you can run into a race condition if that connection is being used in another thread.
Creating new connections should not affect performance as they are pulled from the Connection pool.
You can check if you connection still open before execute query
if (sqlCon.State == System.Data.ConnectionState.Open)
{
insCmd.ExecuteNonQuery();
}
else
{
sqlCon.Open();
insCmd.ExecuteNonQuery();
}
}
You do not you prepare the insert statement by using the StringBuilder and pass it as text to SQL Command to send once over the SQL SERVER to insert. In this case for all 600 loops , you will need to connect to DB once . Just a thought