using Statement And ADO.NET Objects - c#

Consider the following method...
private string[] GetExistingPOWSNumbers()
{
using (
var OleAdapter =
new OleDbDataAdapter(
"SELECT DISTINCT con_num FROM `Items` WHERE con_num LIKE 'POWS%'",
ConfigurationManager.ConnectionStrings["MPOleConnectionString"].ConnectionString))
using (var POWSTable = new DataTable())
{
OleAdapter.SelectCommand.Connection.Open();
OleAdapter.Fill(POWSTable);
return POWSTable.AsEnumerable().Select(row => Convert.ToString(row["con_num"])).ToArray();
}
}
Are all the ADO.NET objects promptly being disposed of? I am using this method throughout my projects and when there are A LOT of calls like these being made during a single action, I receive "Out of Memory" errors.
EDIT: After some personal investigation I discovered that, in fact, the using statement for the adapter DOES NOT also close the provided collection. I made the following change. Now I am using a DataReader instead of populating a DataTable.
private string[] GetExistingPOWSNumbers()
{
var Results = new List<string>();
using (var OleConnection = new OleDbConnection(ConfigurationManager.ConnectionStrings["MPOleConnectionString"].ConnectionString))
using (
var OleCommand =
new OleDbCommand(
"SELECT DISTINCT con_num FROM `Items` WHERE con_num LIKE 'POWS%'",
OleConnection))
{
OleConnection.Open();
using (var OleReader = OleCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
if (OleReader == null) return new string[0];
while (OleReader.Read())
{
Results.Add(OleReader.GetString(0));
}
}
}
return Results.ToArray();
}

Objects will be cleaned up when they are no longer being used and when the garbage collector sees fit. Sometimes, you may need to set an object to null in order to make it go out of scope (such as a static field whose value you no longer need), but overall there is usually no need to set to null.
Regarding disposing objects, I agree with #Andre. If the object is IDisposable it is a good idea to dispose it when you no longer need it, especially if the object uses unmanaged resources. Not disposing unmanaged resources will lead to memory leaks.
You can use the using statement to automatically dispose an object once your program leaves the scope of the using statement.
using (MyIDisposableObject obj = new MyIDisposableObject())
{
// use the object here
} // the object is disposed here
Which is functionally equivalent to:
MyIDisposableObject obj;
try
{
obj = new MyIDisposableObject();
}
finally
{
if (obj != null)
{
((IDisposable)obj).Dispose();
}
}
Got this from Zach Johnson here: Credit Due

Related

Using same disposable object twice in diffrent using-statment [duplicate]

Seeking best inputs on correct usage of C# using statement. Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
Although the code snippet is different from what I feel that the using statement should be in ProcessFileAndReturnNumberFromStream() method of 'Business' class.
Why is it an uncommon practice to use using statement on object passed via parameter? Please correct or elaborate on the flaw?
using System;
using System.IO;
class Data
{
public double? GetNumberFromStream(StreamReader sr)
{
double? number;
try
{
using (sr)
{
number = Convert.ToDouble(sr.ReadToEnd());
return number;
}
}
finally
{
number = null;
}
}
}
class Business
{
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
StreamReader sr = new StreamReader(fileName);
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
}
class GUI
{
static void Main()
{
Business bus = new Business();
double? number = bus.ProcessFileAndReturnNumberFromStream();
Console.WriteLine(number);
Console.ReadKey();
}
}
Please help.
Thanks
If a method is passed an object that implements IDisposable, it's usually the responsibility of the caller to manage the lifetime of that object, rather than the callee.
public double? ProcessFileAndReturnNumberFromStream()
{
string fileName = "Test.txt";
Data dat = new Data();
using (StreamReader sr = new StreamReader(fileName))
{
return dat.GetNumberFromStream(sr);
}
}
The caller that is passing the instance of IDisposable should be the one to use the using statement. If the callee uses it, the object will be disposed while outside the immediate control of the caller who 'owns' the object.
Can I use using statement on a parameter object as in the following uncommon example code snippet (viz., multi-layer application)?
You can, but it's generally odd to do so. Usually whatever is creating the StreamReader would be expecting to "own" it and dispose of it when they're done with it. It would be more usual for your ProcessFileAndReturnNumberFromStream method to be:
using (StreamReader sr = new StreamReader(fileName))
{
Data dat = new Data();
return dat.GetNumberFromStream(sr);
}
(Although I'd personally use File.OpenText instead of explicitly constructing the StreamReader.)
Your GetNumberFromStream method would then not need the using statement. It also doesn't need the try/finally block at all - it's an odd implementation all round, given that it will never return null, either...
It's also odd that you're creating a new instance of Data and then doing nothing with it - as your GetNumberFromStream method doesn't use an instance variables or override a base class method, you should consider making it static.
Such API would be extremely troublesome.
You would never know whether or not the object passed to a method is disposed inside the method or not. Thus, if this is you who create the object and pass it there, you would also never know whether or not you should dispose the object you have just created and passed to the method or not.
I guess then, while this is technically possible, it would promote the bad programming style.

C# 8 Using Declaration Scope Confusion

With the new C# 8 Using Declaration Syntax, what is containing scope of a second consecutive using statement?
TL;DR
Previous to C# 8, having a consecutive using statement like:
using(var disposable = new MemoryStream())
{
using(var secondDisposable = new StreamWriter(disposable))
{}
}
would expand to something like the following (My Source):
MemoryStream disposable = new MemoryStream();
try {
{
StreamWriter secondDisposable = new StreamWriter(disposable);
try{
{}
}
finally {
if(secondDisposable != null) ((IDisposable)secondDisposable).Dispose();
}
}
}
finally {
if(disposable != null) ((IDisposable)disposable).Dispose();
}
I know that there are two other possible expansions but they all are roughly like this
After upgrading to C# 8, Visual studio offered a Code Cleanup suggestion that I'm not certain I believe is an equivalent suggestion.
It converted the above consecutive using statement to:
using var disposable = new MemoryStream();
using var secondDisposable = new StreamWriter(disposable);
To me this changes the second's scope to the same scope as the first. In this case, It would probably coincidentally dispose of the streams in the correct order, but I'm not certain I like to rely on that happy coincidence.
To be clear on what VS asked me to do: I first converted the inner (which made sense because the inner was still contained in the outer's scope). Then I converted the outer (which locally made sense because it was still contained in the method's scope). The combination of these two clean ups is what I'm curious about.
I also recognize that my thinking on this could be slightly (or even dramatically) off, but as I understand it today, this doesn't seem correct. What is missing in my assessment? Am I off base?
The only thing I can think of is that there is some sort of an implicit scope inserted in the expansion for everything following a declaration statement.
In this case, It would probably coincidentally dispose of the streams in the correct order, but I'm not certain I like to rely on that happy coincidence.
From the spec proposal:
The using locals will then be disposed in the reverse order in which they are declared.
So, yes, they already thought about it and do the disposal in the expected order, just as chained using statements would before it.
To Illustrate the Daminen's answer; When you have a method something like;
public void M()
{
using var f1 = new System.IO.MemoryStream(null,true);
using var f2 = new System.IO.MemoryStream(null,true);
using var f3 = new System.IO.MemoryStream(null,true);
}
IL converts it into;
public void M()
{
MemoryStream memoryStream = new MemoryStream(null, true);
try
{
MemoryStream memoryStream2 = new MemoryStream(null, true);
try
{
MemoryStream memoryStream3 = new MemoryStream(null, true);
try
{
}
finally
{
if (memoryStream3 != null)
{
((IDisposable)memoryStream3).Dispose();
}
}
}
finally
{
if (memoryStream2 != null)
{
((IDisposable)memoryStream2).Dispose();
}
}
}
finally
{
if (memoryStream != null)
{
((IDisposable)memoryStream).Dispose();
}
}
}
Which is same as nested using statements
you can check from here: https://sharplab.io/#v2:CYLg1APgAgTAjAWAFBQMwAJboMLoN7LpGYZQAs6AsgBQCU+hxTUADOgG4CGATugGZx0AXnQA7AKYB3THAB0ASQDysyuIC2Ae24BPAMoAXbuM5rqogK4AbSwBpD58bQDcTRkyKsOPfjGFipMgrKqpo6BkYmZla29o5Obu6eXLx8GCIS0lBySirqWnqGxqYW1nbcDs4JAL7IVUA===
I'd like to see the real function that's using this. The compiler won't change scope or sequence of allocations or disposals willy-nilly. If you have a method like:
void foo()
{
using(var ms = new MemoryStream())
{
using(var ms2 = new MemoryStream())
{
/// do something
}
}
}
Then the Dispose() order doesn't matter, so it's safe for the compiler to arrange things however it sees fit. There may be other cases where the order is important, and the compiler should be smart enough to recognize that. I wouldn't file that under "coincidence" so much as "good AST analysis."

Is this a valid object disposal code pattern in method with return?

I noticed the following object disposal code pattern in a C# project and I was wondering if it's acceptable (although it works).
public object GetData()
{
object obj;
try
{
obj = new Object();
// code to populate SortedList
return obj;
}
catch
{
return null;
}
finally
{
if (obj != null)
{
obj.Dispose();
obj = null;
}
}
}
For this example, I'm using a general 'object' instead of the actual IDisposable class in the project.
I know that the 'finally' block will be executed every time, even when the value is returned, but would it affect the return value (or would it be a new object instance) in any way since the object is being set to null (for what seems like object disposal and GC purposes).
Update 1:
I tried the following snippet and the return object is non-null, although the local object is set to null, so it works, which is a bit strange considering some of the comments below:
public StringBuilder TestDate()
{
StringBuilder sb;
try
{
sb = new StringBuilder();
sb.Append(DateTime.UtcNow.ToString());
return sb;
}
catch
{
return null;
}
finally
{
sb = null;
}
}
Btw, I'm using C# 4.0.
P.S. I'm just reviewing this project code. I'm not the original author.
Update 2:
Found the answer to this mystery [1]. The finally statement is executed, but the return value isn't affected (if set/reset in the finally block).
[1] What really happens in a try { return x; } finally { x = null; } statement?
This code will compile fine (assuming that you are not actually using an Object but something that implements IDisposable), but it probably won't do what you want it to do. In C#, you don't get a new object without a new; this code will return a reference to an object that has already been disposed, and depending on the object and what Dispose() actually does, trying to use a disposed object may or may not crash your program.
I assume the idea is to create an object, do some stuff with it, then return the object if successful or null (and dispose the object) on failure. If so, what you should do is:
try {
obj = new MyClass();
// ... do some stuff with obj
return obj;
}
catch {
if(obj != null) obj.Dispose();
return null;
}
Simply using the using statement achieves the same result as that, and is the standard practice
public int A()
{
using(IDisposable obj = new MyClass())
{
//...
return something;
}
}
I would, however, advise against returning your IDisposable object.
When you dispose of an object, it is supposed to be considered "unusable". And so, why return it?
If the object's lifetime needs to be longer than the method A's lifetime, consider having the calling method B instantiate the object, and pass it as a parameter to method A.
In this case, method Bwould be the one using the using statement, inside which it would call A.
If you are returning an IDisposable object, then it is the responsibility of your caller to dispose of it:
public IDisposable MakeDisposableObject()
{
return new SqlConnection(""); // or whatever
}
caller:
using (var obj = MakeDisposableObject())
{
}
It makes less than no sense for your method to dispose of an object and then return it. The disposed object will be of no value to the caller. In general, referencing a disposable object which has been disposed should produce an ObjectDisposedException.
A few observations.
That code wouldn't compile because object doesn't have a .Dispose() method.
Why wouldn't you use IDisposable?
Why would you dispose of an object that is being returned, since returning you would return an object for the purpose of some other code to use it. The concept of "disposing" of something is to give it a chance to clean up after itself and its used, un-managed resources. If you are returning an object that is supposed to be used elsewhere, but has unmanaged resources that you want to clean up before the object gets used anywhere else, then you shuld really have 2 separate objects. One to load some data that would be disposable, and another object that would contain the usable loaded content that you want to pass around. An example of this would be something like stream readers in the .NET framework. You would normally new a stream reader, read it into a byte[] or some other data object, .Dispose() the stream reader, then return the byte[]. The "loader" that has some resources to dispose of in a timely fashion is separate from the object containing the "loaded" data that can be used without needing to be disposed.

A using block, with an object initializer block in the constructor

If you call a constructor from a within a using statement the object is automatically disposed is wrapped it with a try/catch block. That is an object initializer block in the constructor.
But what becomes with member types that are initialized in the same statement? e.g:
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException m = new TypeThatThrowsAnException()
})
{
// inside using statement
ds.doSomething();
}
What happens with MemberThatThrowsAnException when it throws an exception when SomeDisposable is initialized, i.e., the code block is executed?
And does it make any difference if we call those members constructors outside the scope of the using block?
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
class SomeClass
{
public static TypeThatThrowsAnException StaticMember
{
get
{
return new TypeThatThrowsAnException();
}
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException = SomeClass.StaticMember
})
{
// inside using statement
ds.doSomething();
}
In some scenarios this can be pretty nice and readable, but I would like to know if thare are any caveats or pitfalls in this way. Or that it is a no-go all the way. Besides that you need to keep the readability in mind.
Object initializers are in some sense a red herring here... but they're one example of where a problem is avoidable.
The object isn't "guarded" by the using statement until the resource acquisition expression has completed normally. In other words, your code is like this:
SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();
using (SomeDisposable ds = tmp)
{
// Stuff
}
That's more obviously problematic :)
Of course the solution is to assign the property inside the using statement:
using (SomeDisposable ds = new SomeDisposable())
{
MemberThatThrowsAnException = new TypeThatThrowsAnException();
// Stuff
}
Now we're only relying on the constructor of SomeDisposable to clean up after itself if it ends up throwing an exception - and that's a more reasonable requirement.
Find this post on Ayende's blog on the subject. It's about object initializers in using statements but it seems somehow related to your question.
From what I can see, your SomeDisposable class has a property of type TypeThatThrowsAnException, that you're initializing as you instantiate the SomeDisposable - yes ?
using () i.e. the Dispose pattern is a short-hand that actually emits this: -
SomeDisposable ds = null;
try
{
ds = new SomeDisposable();
}
finally
{
if (ds != null)
ds.Dispose();
}
So if the constructor for your type throws an exception, control will immediately pass to the finally block.

return the variable used for using inside the using C#

I am returning the variable I am creating in a using statement inside the using statement (sounds funny):
public DataTable foo ()
{
using (DataTable properties = new DataTable())
{
// do something
return properties;
}
}
Will this Dispose the properties variable??
After doing this am still getting this Warning:
Warning 34 CA2000 : Microsoft.Reliability : In method 'test.test', call System.IDisposable.Dispose on object 'properties' before all references to it are out of scope.
Any Ideas?
Thanks
If you want to return it, you can't wrap it in a using statement, because once you leave the braces, it goes out of scope and gets disposed.
You will have to instantiate it like this:
public DataTable Foo()
{
DataTable properties = new DataTable();
return properties;
}
and call Dispose() on it later.
Yes, it will dispose it - and then return it. This is almost always a bad thing to do.
In fact for DataTable, Dispose almost never does anything (the exception being if it's remoted somewhere, IIRC) but it's still a generally bad idea. Normally you should regard disposed objects as being unusable.
Supposedly, this is the pattern for a factory method that creates a disposable object. But, I've still seen Code Analysis complain about this, too:
Wrapper tempWrapper = null;
Wrapper wrapper = null;
try
{
tempWrapper = new Wrapper(callback);
Initialize(tempWrapper);
wrapper = tempWrapper;
tempWrapper = null;
}
finally
{
if (tempWrapper != null)
tempWrapper.Dispose();
}
return wrapper;
This should guarantee that if the initialization fails, the object is properly disposed, but if everything succeeds, an undisposed instance is returned from the method.
MSDN Article: CA2000: Dispose objects before losing scope.
Yes. Why are you using the using keyword on something you don't want disposed at the end of the code block?
The purpose of the using keyword is to dispose of the object.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
The point of a using block is to create an artificial scope for a value/object. When the using block completes, the object is cleaned up because it is no longer needed. If you really want to return the object you are creating, than it is not a case where you want to use using.
This will work just fine.
public DataTable foo ()
{
DataTable properties = new DataTable();
// do something
return properties;
}
Your code using the using keyword expands to:
{
DataTable properties = new DataTable();
try
{
//do something
return properties;
}
finally
{
if(properties != null)
{
((IDisposable)properties).Dispose();
}
}
}
Your variable is being disposed by nature of how using works. If you want to be able to return properties, don't wrap it in a using block.
The other responses are correct: as soon as you exit the using block, your object is disposed. The using block is great for making sure that an object gets disposed in a timely manner, so if you don't want to rely on the consumers of your function to remember to dispose the object later, you can try something like this:
public void UsingDataContext (Action<DataContext> action)
{
using (DataContext ctx = new DataContext())
{
action(ctx)
}
}
This way you can say something like:
var user = GetNewUserInfo();
UsingDataContext(c => c.UserSet.Add(user));

Categories