ExecuteReader requires an open connection - sqlconnection

I am getting the error: "ExecuteReader requires an open connection" and I know the fix is to add a connection.Open() / connection.Close(). My question pertaining to this error is more for me to understand exactly what happen under the hood.
I am currently using the "USING" statement which I expect it to open and close/dispose the connection for me. So I guess I don't understand why it didn't work as expected and I needed to explicitly code the connection.Open() / connection.Close() myself to fix the issue. I did some research and found people experienced similar issue because they were using static connection. In my case, I am creating a new instance of the connection... hence, it bothers me and hoping to get to the bottom of this instead of just fix it and move on. Thank you in advance.
Here is the code:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
using (SqlCommand command = new SqlCommand("mySPname", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
catch (Exception ex)
{
throw;
}

Using does not open any connections, it only disposes of any allocated memory after calling End Using.

For the SqlConnection, you have to explicitly open it inside the using block, you just don't need to close it though.
I also notice that you are missing a set of brackets {} around the using SqlConnection. Maybe that's the issue? It should be like this:
try
{
using (SqlConnection connection = new SqlConnection(myConnStr))
{
connection.Open();
using (SqlCommand command = new SqlCommand("InsertProcessedPnLFile", connection))
{
command.CommandType = CommandType.StoredProcedure;
//add some parameters
SqlParameter retParam = command.Parameters.Add("#RetVal", SqlDbType.VarChar);
retParam.Direction = ParameterDirection.ReturnValue;
/////////////////////////////////////////////////
// fix - add this line of code: connection.Open();
/////////////////////////////////////////////////
using(SqlDataReader dr = command.ExecuteReader())
{
int success = (int)retParam.Value;
// manually close the connection here if manually open it. Code: connection.Close();
return Convert.ToBoolean(success);
}
}
}
}

Related

should I set T-SQL command timeout back to default?

I hope this question is not too stupid. I have a long process t-sql command in my ADO.Net. I would like to increase the command timeout (please see below).
cmd.CommandTimeout = 600; // default is 30 sec. increase to 10 mins
try
{
cmd.ExecuteNonQuery();
cmd.CommandTimeout = 30; // set it back
}
catch (Exception ex)
{
string debug = ex.Message;
throw ex;
}
Should I set the timeout back to default after the long process is done? I am looking for the best practice. Thank you :-)
If you re-use the command object, you can add a finally to the try-catch, so it will be reset regardless of the result of the query. (success or exception).
But when you dispose the SqlCommand after you've used it. There's no need to reset the CommandTimeout
The best practice is to not reuse the command because you should not be reusing the connection. Holding a connection is not good for scale.
static private dbConnectionString = "CONNECTION DETAILS";
using (SQLConnection connection = new SQLConnection(dbConnectionString))
{
try
{
connection.Open();
using (SQLCommand command = connection.CreateCommand())
{
command.CommandTimeout = 600;
......
using(SQLDataReader rdr = command.ExecuteReader())
{
}
}
}
catch(SQLException ex)
{
}
finally
{
connection.Close();
}
}

MessageQueue Quirks while Sending Messages

Writing to remote MSMQ seems to be working on/off. I am not sure what is wrong and what else to do to confirm sending.
I am reluctant to setup some kind of ack. It seems to be an overkill.
using (var queue = new MessageQueue(queueName, QueueAccessMode.Send))
{
var messageQueueTransaction = new MessageQueueTransaction();
messageQueueTransaction.Begin();
try
{
queue.Formatter = new XmlMessageFormatter(new Type[] { typeof(EmailMessage) });
var msg = new Message();
msg.Label = emailMessage.Subject;
msg.Body = emailMessage;
queue.Send(msg, messageQueueTransaction);
messageQueueTransaction.Commit();
}
catch (Exception e)
{
LoggerLib.Logger.ErrorException(e, "Error Sending Email using MSMQ", emailMessage);
messageQueueTransaction.Abort();
}
finally
{
queue.Close();
}
}
The Connection string for MSMQ is in the format of:"FormatName:DIRECT=OS:FULLMACHINENAME\private$\emailmessagequeue"
Also, I used "FormatName:DIRECT:TCP:IPAddress\private$\emailmessagequeue".
It works without a glitch when I ran it locally. So, I allowed Everyone to have Full access and It still doesn't work.
Any ideas?
The port number 1801 was blocked. That resolved it. –

quickfix SocketInitiator has no response and no exception

I'm trying to connect to a ForexTrading broker FIX API and do some trading.
I tried my best to read through the Quickfix for .net. and almost understand the process of how the quickfix works. However, when I try to initiate the socketinitiator, I failed to do that and there are no complaints and exceptions from VS 2012. It is simply stuck there.
Here's my code:
private void iFind_ItemClick(object sender, ItemClickEventArgs e)
{
try
{
QuickFix.SessionSettings settings = new QuickFix.SessionSettings("C:\\Users\\Administrator\\Documents\\My Box Files(shewenhao#hotmail.com)\\Work With Mr.Liu\\ForexAutoTradingSystem\\ForexAutoTradingSystem\\integralfix.cfg");
IntegralFixAPI integralFixAPIApplication = new IntegralFixAPI();
QuickFix.IMessageStoreFactory storeFactory = new QuickFix.FileStoreFactory(settings);
QuickFix.ILogFactory logFactory = new QuickFix.ScreenLogFactory(settings);
QuickFix.Transport.SocketInitiator initiator = new QuickFix.Transport.SocketInitiator(
integralFixAPIApplication, storeFactory, settings, logFactory);
MessageBox.Show(settings.ToString());
integralFixAPIApplication.MyInitiator = initiator;
initiator.Start();
while (true)
{
Thread.Sleep(200);
MessageBox.Show("true");
}
//initiator.Stop();
}
catch (System.Exception systeme)
{
Console.WriteLine(systeme.Message);
Console.WriteLine(systeme.StackTrace);
}
}
You may notice that I have a MessageBox right below the SocketInitiator and it pops up before this QuickFix.Transport.SocketInitiator line. I do not get it that why I failed at this point. On the page of quickfix .Net http://quickfixn.org/tutorial/creating-an-application, it says that you simply need to replace the threadedacceptor with the socketinitiator. However, I can not pass through this initiation line.

ADO.NET and Disposing without Using

I have a project that isn't using USING anywhere with their ADO.NET code. I am cleaning up their unclosed connections. Is the below code a best practice with try/catch/finally. I also have some that contains SqlTransaction that I'm disposing in between the command and connection dispose.
SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString());
SqlCommand cmd = new SqlCommand();
DataSet ds = new DataSet();
try
{
con.Open();
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch (Exception ex)
{
throw ex;
}
finally
{
cmd.Dispose();
con.Dispose();
}
Actually, there is no need to worry about closing the connection when using the SqlDataAdapter.Fill(dataset) method. This method closes the connection after performing every Fill.
Also, there is no need to call SqlCommand.Dispose() since the command itself has no unmanaged resources to clean up. What you should be concerned about is if SqlConnection.Close() is called at some point. This is done after Fill.
What you have is fine. It is always a good idea to dispose of objects that use unmanaged resources. However, if you get sick of always explicitly calling Dispose, the best practice is probably to use the using:
using (SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString()))
{
using (SqlCommand cmd = new SqlCommand())
{
DataSet ds = new DataSet();
try
{
con.Open();
cmd.Connection = con;
SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(ds);
}
catch (Exception ex)
{
throw; // I changed this too!
}
}
}
Also, you almost always want to simply throw if you're going to "rethrow" an exception. You lose some of your stack trace if you throw ex;.
The best practice is using using instead of try/finally :)
However in your case even using is not needed, because Fill() closes the connection:
SqlConnection con = new SqlConnection(ConfigurationManager.AppSettings["MyNGConnectDashBoardConnectionString"].ToString())
SqlDataAdapter da = new SqlDataAdapter("your sql is here", con);
da.Fill(ds);
Also simple re-throwing exceptions makes no sense at all. If you need to log error, just use plain throw; as #Cory suggested.

Trouble Calling Stored Procedure from BackgroundWorker

I'm in ASP.NET MVC and am (mostly) using Entity Framework. I want to call a stored procedure without waiting for it to finish. My current approach is to use a background worker. Trouble is, it works fine without using the background worker, but fails to execute with it.
In the DoWork event handler when I call
command.ExecuteNonQuery();
it just "disappears" (never gets to next line in debug mode).
Anyone have tips on calling a sproc asynchronously? BTW, it'll be SQL Azure in production if that matters; for now SQL Server 2008.
public void ExecAsyncUpdateMemberScoreRecalc(MemberScoreRecalcInstruction instruction)
{
var bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(AsyncUpdateMemberScoreRecalc_DoWork);
bw.WorkerReportsProgress = false;
bw.WorkerSupportsCancellation = false;
bw.RunWorkerAsync(instruction);
}
private void AsyncUpdateMemberScoreRecalc_DoWork(object sender, DoWorkEventArgs e)
{
var instruction = (MemberScoreRecalcInstruction)e.Argument;
string connectionString = string.Empty;
using (var sprocEntities = new DSAsyncSprocEntities()) // getting the connection string
{
connectionString = sprocEntities.Connection.ConnectionString;
}
using (var connection = new EntityConnection(connectionString))
{
connection.Open();
EntityCommand command = connection.CreateCommand();
command.CommandText = DSConstants.Sproc_MemberScoreRecalc;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.AddWithValue(DSConstants.Sproc_MemberScoreRecalc_Param_SageUserId, instruction.SageUserId);
command.Parameters.AddWithValue(DSConstants.Sproc_MemberScoreRecalc_Param_EventType, instruction.EventType);
command.Parameters.AddWithValue(DSConstants.Sproc_MemberScoreRecalc_Param_EventCode, instruction.EventCode);
command.Parameters.AddWithValue(DSConstants.Sproc_MemberScoreRecalc_Param_EventParamId, instruction.EventParamId);
int result = 0;
// NEVER RETURNS FROM RUNNING NEXT LINE (and never executes)... yet it works if I do the same thing directly in the main thread.
result = command.ExecuteNonQuery();
}
}
Add a try catch around the call and see if any exceptions are caught and are thus aborting the thread.
try {
result = command.ExecuteNonQuery();
} catch(Exception ex) {
// Log this error and if needed handle or
throw;
}