This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I'm struggling with some System.Data.SqlClient.SqlDataReader problems.
Actually, I made a DatabaseHandler for execute queries more convenient, with IDisposable interface for using statements.
When I use the handler for reading single article, query successfully executed, however, the handler disposed before I use data.
Then, the result is NullReferenceException. Here's the article reading code, and Dispose().
// Article Reading Code
using (var ArticleHandler = new DatabaseHandler())
{
var ArticleReader = ArticleHandler.ExecuteCommand("ARTICLE_INQUIRY",
DatabaseHandler.QueryType.ExecuteReader,
new DatabaseParameter[]
{
new DatabaseParameter("seq", Sequence)
}) as System.Data.SqlClient.SqlDataReader; //Query Successful
if (!ArticleReader.HasRows)
{
Response.Redirect("/articles/list.aspx");
}
else
{
ArticleReader.Read(); //Data Read Successful
CurrentArticle.title = (string)ArticleReader["title"]; //NullReferenceException ?
CurrentArticle.category = (string)ArticleReader["category"];
CurrentArticle.datetime = (string)ArticleReader["written_datetime"];
CurrentArticle.content = (string)ArticleReader["content"];
}
}
/* Database Handler Dispose() */
public void Dispose()
{
CurrentConnection = null;
}
P.S. I checked column names, and they are match with database information.
Check inside your database handler if you are closing the underlying sqlconnection before accessing the reader to access data in the next line. If the sqlconnection is getting closed, the reader will get closes automatically. Paste the handler Execute command code so we can have look at it
Related
This question already has answers here:
Dispose object that has been instantiated as method parameter c#
(2 answers)
Closed 3 years ago.
PREAMBLE
I understand that normally most SQL calls run thusly
using(var cnn = new DbConnection("YOURCONNECTIONSTRINGHERE")
{
cnn.Open(); //Open the connection.
using(var cmd = new DbCommand("YourSQL", cnn)
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
}
This will properly dispose of both the connection and the command.
My Question: Will this code properly dispose of both objects?
using(var cmd = new SqlCommand("YourSQL", new Connection("YOURCONNECTIONSTRINGHERE"))
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
In reality I'm using a method that provides and opens the connection.
public SqlConnection Connection()
{
var product = new SQLConnection("ConnectionString");
product.Open();
return product;
}
So at the end of the day the call looks like this:
using(var cmd = new SqlCommand("YourSQL", Connection())
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
I know the SqlCommand object will be disposed of but will the SQLConnection, created within the using parameter declaration, be disposed of? I've tried running some simple unit tests but it seems inconclusive.
Will this code properly dispose of both objects?
using(var cmd = new SqlCommand("YourSQL", new Connection("YOURCONNECTIONSTRINGHERE"))
{
cmd.ExecuteScalar; //Or whatever type of execution you want.
}
The above code does not call Dispose() on the connection. The using block ensures that cmd.Dispose() is called immediately after the execution of the block, but the connection remains open. Since the connection has no object referencing it, it will be eventually closed/disposed by the Garbage Collector.
If you want to dispose the Command and Connection immediately, then try:
using (var con = Connection()) // <-- GetConnection() would be a better name
using (var cmd = new SqlCommand(con)
{
cmd.ExecuteScalar;
}
This question already has answers here:
Is it a good approach to call return inside using {} statement?
(6 answers)
Closed 9 years ago.
will a construct like this, dispose the filehandle correctly?
void bla() {
using (var stream = new new System.IO.StreamReader( filename)) {
return DoSomethingWithTheStream(stream);
}
}
i.e. will the using trigger the Dispose even though it is returned inside?
This is equivalent to:
var stream = new StreamReader(fileName);
try {
return DoSomethingWithTheStream(stream);
}
finally {
stream.Dispose();
}
Since finally clauses are guaranteed to execute, it's guaranteed that the stream is disposed before returning from the method.
Yes. No matter how the block is left, the resource is disposed. This is the value of the using-block.
Yes, it will dispose correctly.
Yes, as soon as stream goes out of scope it will be disposed.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
in a “using” block is a SqlConnection closed on return or exception?
Would this using close this _connection?
using(SqlConnection _connection = Class1.GetSqlConnection())
{ //code inside the connection
}
//connection should be closed/ended?
I'm just wondering because GetSqlConnection() is a static function of Class1 and the whole connection might not be closed because it is calling outside class' static function instead of straight?
using(SqlConnection _connection = new SqlConnection(_connectionString)
{ //code inside the connection
}
The using statement does not care how the variable gets its value, - be it from a static function, a member function, a new operator, or any other way. As soon as the closing brace of the using is reached, the Dispose() method on the variable will be called, closing the connection if it's an IDbConnection instance, or doing whatever else the IDisposable is to do upon disposing.
Yes it does.
Here is an alternative way to implement the GetSqlFunction method so that you have a more explicit behaviour:
public class Class1
{
private static SqlConnection GetSqlConnection() { /* unchanged */ }
public static void UseSqlConnection(Action<SqlConnection> action)
{
using (var connection = Class1.GetSqlConnection())
{
action(connection);
}
}
}
Then you call it like so:
Class1.UseSqlConnection(c =>
{
/* use connection here */
});
You could then extend this method to use an existing connection or create a new one depending on the semantics you prefer.
Yes, by design.
A using block is used to handle disposing of, well, disposable objects when the block ends. To Dispose() an object means to release all of the resources for that object. For objects such as SqlConnection, this will close their connection.
Today I noticed a snippet of code that looks like the one below:
public class Test
{
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
SqlConnection connection2 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c2"].ToString());
public void Method1()
{
using (connection1)
{
connection1.Open();
using (SqlCommand newSqlCommand = new SqlCommand("text",connection2))
{
// do something
}
}
}
public void Method2()
{
using (connection1)
{
// do something
}
}
}
I am just wondering why would anyone want to open the connection when creating the class and not when calling the corresponding methods inside the class?
EDIT: I should have probably posted the whole code instead. So I do see where they are opening connection1, but then they are instantiating a sqlcommand with a different sql connection (connection2) which has not been opened anywhere. What am I missing here?
Thanks,
This line only initializes a connection object, which can later be used to open a connection to a database server.
SqlConnection connection1 =
new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
What I know is that using disposes of an object (and in the case of Connection objects they are automatically closed) after its scope so I wouldn't recommend such usage because it might be problematic with other object types (other than Connection) that can't be used after having their dispose called.
connection1 = new SqlConnection(...) does not really open the connection. It just creates the connection object.
You have to call connection1.Open(); to actually open it. You can do this inside using statement block.
Refer to this MSDN page for more details.
It either
written this way to enforce only single call to a method be performed on the class
unintentionally confusing by throwing ObjectDisposed exception if you call 2 methods
contains connection re-initialization code in blocks you've ommited.
The code is dangerous.
If you call Method1 then Method2 (or visa versa) you will get an error (connection string not initialized).
The error occurs because the using statement will close the connection AND Disposes the object. I double checked what happens when dispose is called...the connection string is cleared (and possibly some other things I didn't notice).
You don't want to re-use a disposed object.
The cost of instantiating a new connection object is insignificant so I would just create the object where needed, maybe with a little factory method to reduce code duplication, so change to something like:-
private static SqlConnection GetSqlConnection()
{
return new SqlConnection(ConfigurationManager.ConnectionStrings["c1"].ToString());
}
private void Method1()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do stuff...
}
}
private void Method2()
{
using (var conn = GetSqlConnection())
{
conn.Open();
// do other stuff...
}
}
Of course there are many different ways of approaching this problem, this is just one and indeed quite a simplistic one...but it is a good starting point and is safe :-)
I have a .NET 4 C# console application. It pulls data from our IBM i and sends it to our internet SQL Server. It works perfect until it ends, I get the following error:
System.ObjectDisposedException was unhandled Message=Safe handle has
been closed Source=mscorlib ObjectName="" StackTrace:
at System.Runtime.InteropServices.SafeHandle.DangerousRelease()
at System.Threading.RegisteredWaitHandleSafe.Finalize() InnerException:
My program code is:
class Program
{
static void Main(string[] args)
{
System.Console.WriteLine("Begin: " + DateTime.Now.ToString());
SystemCodeController sc = new SystemCodeController();
sc.SyncSystemCodes();
ParkingTicketController pt = new ParkingTicketController();
pt.SyncParkingTickets();
EmailHelper.SendSuccessEmail();
System.Console.WriteLine("End: " + DateTime.Now.ToString());
}
}
In the console, I see the begin time and the end time. So I know the final line does get executed. What am I forgetting or not doing that I should be?
Update: The Sync* methods pull data from the IBM into an object then uses entity framework to insert the records into the database.
public void SyncParkingTickets()
{
ptr.ClearTable();
ptr.InsertNewCitation(ibmI.GetAllCitations());
ptr.SaveChanges();
}
public void InsertNewCitation(IEnumerable<ParkingTicket> citations)
{
foreach (ParkingTicket citation in citations)
{
InsertNewCitation(citation);
}
}
public void InsertNewCitation(ParkingTicket citation)
{
db.AddToParkingTickets(citation);
}
public IEnumerable<ParkingTicket> GetAllCitations()
{
SystemCodeRepository scr = new SystemCodeRepository();
// Create SQL statement
DataTable dt = new DataTable();
using (iDB2Connection conn = new iDB2Connection(_connString))
{
using (iDB2Command cmd = new iDB2Command(sb.ToString(), conn))
{
conn.Open();
using (iDB2DataAdapter da = new iDB2DataAdapter(cmd)) { da.Fill(dt); }
conn.Close();
}
}
#region Fill object from DataTable
var citations = from i in dt.AsEnumerable()
select new ParkingTicket
{
// Fill object
};
#endregion
return citations;
}
All of the methods operate similar to this one.
A little bit of Googling reveals some scattered reports of the same error when using the iDB2Connection family of database access methods. Evidently IBM is relying on .Net 1.1 handling of EventHandles which changed in the move to .Net 2.0 per this Connect article.
It seems the only reprieve is to update to the latest version of the IBM drivers (using the S21917 service pack for 5.3 or SI37892 for 5.4 as you note).
Are you calling Close() on the SafeWaitHandle for a WaitHandle?
WaitHandle wh = ...;
wh.SafeWaitHandle.Close(); // will throw ObjectDisposedException
From MSDN:
When you assign a new value to the SafeWaitHandle property, the previous handle will be closed when the previous SafeWaitHandle object is collected. Do not manually close the handle, because this results in an ObjectDisposedException when the SafeWaitHandle attempts to close the handle.
Are any of your types Disposable? Try disposing all of your disposable resources before exiting the application.
I have an equal situation. The problem there is that a P/Invoke call in SafeHandle.ReleaseHandle does some magic and calls System.Runtime.InteropServices.SafeHandle.DangerousAddRef(Boolean& success), which tries to do something with the SafeHandle after it was disposed.
Its not your own SafeHandle implementation isn't it? Otherwise you could have tried extending CriticalHandle instead.