I made a simple Console Application. (Code below).
When I run the program on my computer, it works fine. However, when I run it on our server (Windows Server 2008) which is a virtual machine, after a minute of so, the process takes all the CPU. It goes to 100% usage until I close the application.. The only difference I can think of would be that the database on my computer is local and on the server, the database used is on another machine..
Any idea what could cause the CPU to go crazy...?
static void Usings()
{
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]))
{
conn.Open();
SqlCommand cmd = new SqlCommand("SELECT GETDATE()", conn);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
Console.WriteLine(dr[0].ToString());
dr.Dispose();
cmd.Dispose();
}
Console.ReadKey();
}
UPDATE
I modified the code to only open a SqlConnection and I still get the behaviour.
I also added some code to get notified on the Garbage Collector Approach. The CPU goes to the top milliseconds before I receive the notification. So I suspect the garbage collector to be responsible for this. Any clue? Suggestion where I could dig deeper?
New code:
static void Main(string[] args)
{
#region Register for Garbage Collector Notifications
GC.RegisterForFullGCNotification(10, 10);
// Start a thread using WaitForFullGCProc.
Thread thWaitForFullGC = new Thread(new ThreadStart(WaitForFullGCProc));
thWaitForFullGC.Start();
#endregion
using (SqlConnection conn = new SqlConnection(ConfigurationManager.AppSettings["ConnectionString"]))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT GETDATE()", conn))
{ }
}
_sw.Start();
Log("Waits for key press...");
Console.Read();
}
PS: If I do not open the SQL Connection, CPU stays stable (0%)....
When the program starts...
After exactly 3 minutes 11 seconds and some ms...
Related
I was getting quite often the following error:
Npgsql.NpgsqlException: 'The connection pool has been exhausted, either raise MaxPoolSize (currently 100) or Timeout (currently 15 seconds)'
Then I looked for possible causes and solutions in here and found out that I should be applying the using statement. So I reviewed all my code and did that.
However, I keep getting that error while testing a button that gets information from my database, does some calculation and writes the results in a few textboxes. It usually crashes at the fifth-ish time I click it. A piece of the code follows:
private void CalcTemp(Cable cable)
{
string sqlString = "Server=172.19.2.40; Port=5432; User Id=postgres; Password=password; Database=PROLIG;";
using (NpgsqlConnection sqlCon = new NpgsqlConnection(sqlString))
{
string cmdString = #"SELECT tempamb, elevmaxonan, elevmaxonaf, elevmaxonaf2, topoil1_2, topoil1_4, especial1factor, especial1topoil,
especial2factor, especial2topoil, especial3factor, especial3topoil, especial4factor, especial4topoil,
especial5factor, especial5topoil, especial6factor, especial6topoil FROM correntes WHERE prolig_ofs_id = #id;";
NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon);
sqlCmd.Parameters.AddWithValue("id", StartOF.MyOF.id);
NpgsqlDataAdapter sqlDa = new NpgsqlDataAdapter(sqlCmd);
DataTable dt = new DataTable();
sqlDa.Fill(dt);
//does calculation
}
Any thoughts on why this is happening and how to fix it?
Thanks a lot.
Just add using to your command creation:
using (NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon))
{
Disposing all objects which implement IDisposable is a good practice.
Since your command is not disposed of in time, your connection is not closed and returned to the pool.
It is a lot of stuff on dispose which must be executed directly (or by using).
protected override void Dispose(bool disposing)
{
if (State == CommandState.Disposed)
return;
if (disposing)
{
// Note: we only actually perform cleanup here if called from Dispose() (disposing=true), and not
// if called from a finalizer (disposing=false). This is because we cannot perform any SQL
// operations from the finalizer (connection may be in use by someone else).
// We can implement a queue-based solution that will perform cleanup during the next possible
// window, but this isn't trivial (should not occur in transactions because of possible exceptions,
// etc.).
if (_prepared == PrepareStatus.Prepared)
_connector.ExecuteBlind("DEALLOCATE " + _planName);
}
Transaction = null;
Connection = null;
State = CommandState.Disposed;
base.Dispose(disposing);
}
So you need the following code:
private void CalcTemp(Cable cable)
{
string sqlString = "Server=172.19.2.40; Port=5432; User Id=postgres; Password=password; Database=PROLIG;";
using (NpgsqlConnection sqlCon = new NpgsqlConnection(sqlString))
{
string cmdString = #"SELECT * FROM correntes WHERE prolig_ofs_id = #id;";
using (NpgsqlCommand sqlCmd = new NpgsqlCommand(cmdString, sqlCon))
{
sqlCmd.Parameters.AddWithValue("id", StartOF.MyOF.id);
NpgsqlDataAdapter sqlDa = new NpgsqlDataAdapter(sqlCmd);
DataTable dt = new DataTable();
sqlDa.Fill(dt);
//does calculation
} //end using command (calls dispose on command, even if exception happens)
} //end using connection (calls dispose on connection object, even if exception happens)
}
Next advice - do not use data tables in case of large amount of data. Use DataReader instead.
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 c# program working with a SQL Server database running on different client PCs.
Now, I am getting this exception which [if not catched] closes my application:
Transaction (Process ID ...) was deadlocked on lock | communication
buffer resources with another process and has been chosen as the
deadlock victim. Rerun the transaction.
and the stack trace shows that the exception happens here:
at Gui.DB.sqlServerWrapper.MarkAsNonFreshSample(String barcode, Int32 devID)
Where the mentioned method is this:
public void MarkAsNonFreshSample(string barcode, int devID)
{
mux.WaitOne();
var sql = "DELETE FROM results WHERE barcode=#barcode AND devID=#devID";
var command = new SqlCommand(sql, conn);
command.Parameters.AddWithValue("barcode", barcode);
command.Parameters.AddWithValue("devID", devID);
command.ExecuteNonQuery();
mux.ReleaseMutex();
}
I am using the "mux" mutex to exclusive access to the sql connection "conn" because my program has multiple threads.
I am not using a complex query or a long transaction (and I guess this short query is one transaction which should not cause a deadlock. am I wrong?).
Where is the problem and how I should fix it?
Sharing a connection like that is not a good practice
public void MarkAsNonFreshSample(string barcode, int devID)
{
using (SqlConnection con = new SqlConnection(conString))
{
con.Open();
using (SqlCommand command = con.CreateCommand())
{
command.CommandText = "DELETE FROM results WHERE barcode=#barcode AND devID=#devID";
command.Parameters.AddWithValue("barcode", barcode);
command.Parameters.AddWithValue("devID", devID);
command.ExecuteNonQuery();
}
}
}
Please read entire question before responding. And I apologize, I never seem to write short questions...
I am supporting a C# internal web app that hits SQL Server 2008 R2 running on a Windows Small Business Server 2011 SP1 box.
We have been getting a lot of SQL timeouts lately, here is an example exception:
System.Web.HttpUnhandledException: Exception of type 'System.Web.HttpUnhandledException' was thrown. ---> System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
at System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)
at System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory)
at System.Data.SqlClient.SqlConnection.Open()
I have checked a few things, one of them being how the code handles connections and closing of connections. I have read in other threads that using a Using statement with your connection is adequate as it "...wraps the connection create in a try .. finally and places the connection disposal call inside the finally". The connection is closed even in the event of an exception.
So, I agree with and have used that method for years. Others have recommended explicitly closing connections even when using a Using statement with your connection. I think that would be redundant...
My question, however, is regarding the command object. Someone else wrote a large library of db methods for this app and they have (in all of the db methods) declared the SqlCommand object BEFORE the SqlConnection object using statement. They have also assigned the connection object to the command object before the connection using statement.
Is it better practice to declare and use the command object inside the connection using statement, and could doing it the other way cause sql connection timeouts (barring other causes of sql connection timeouts)? Take this code for example:
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
SqlConnection con = new SqlConnection(_connectionString);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", recordId);
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int)reader["id"]);
objMusician.Name = (string)reader["name"];
}
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
return objMusician;
}
Also know that the calling pages have try catches in them and it is the page that logs the error to our logging db. We let the exception bubble up to the calling method on the page, and it gets handled there.
You should explicitly close the connection when you're finished with it. You're never closing any connections so after you hit the connection pool limit you're going to get errors until you manually recycle the pool or it cycles on its own. Move the property assignment block inside the using block and do a con.Close(); cmd.Dispose(); before returning your objMusician:
using (con)
{
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int)reader["id"]);
objMusician.Name = (string)reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
con.Close();
cmd.Dispose();
return objMusician;
}
Don't know if it will help your timeout problem, but I've always structured my code like the following and not had that problem:
using(var cmd = new SqlCommand())
{
using(var con = new SqlConnection(ConnectionString))
{
con.Open();
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", recordId);
...
}
}
Was just reading on MSDN, it said "Call Dispose when you are finished using the Component. The Dispose method leaves the Component in an unusable state. After calling Dispose, you must release all references to the Component so the garbage collector can reclaim the memory that the Component was occupying." This means in order for the GC to immediately collect the connection, you must dispose the connection before disposing the command, otherwise the connection hangs around until the GC gets around to calling the Finalize on it.
Refactor your method as follows. You are likely running into a situation where a data reader has a reference to a connection, and it has not yet been disposed of.
public Musician GetMusician(int recordId)
{
Musician objMusician = null;
using(SqlConnection con = new SqlConnection(_connectionString))
{
con.Open();
using (SqlCommand cmd = new SqlCommand())
{
cmd.Connection = con;
cmd.CommandText = "selectMusician";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#id", recordId);
using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
if (reader.HasRows)
{
reader.Read();
objMusician = new Musician((int) reader["id"]);
objMusician.Name = (string) reader["name"];
}
if objMusician != null)
{
objMusician.Albums = Albums.GetAlbums((int)objMusician.ID);
objMusician.Tours = Tours.GetTours((int)objMusician.ID);
objMusician.Interviews = Interviews.GetInterviews((int)objMusician.ID);
}
}
}
return objMusician;
}
}
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