using and method parameter passing - c#

I am use using to guarantee the resource cleanup. This is fine for the simple block of code.
If I have a method which I need to pass the variable inside the using, can I still guarantee resource clean up?
for example,
using ( FileStream fs = -----)
{
SomeMethod(fs);
}

Yes. using(){} is syntactic sugar, and it will expand your code to this:
FileStream fs = -----;
try {
SomeMethod(fs);
} finally {
if (fs != null)
((IDisposable)fs).Dispose();
}
finally blocks are guaranteed to execute whether an exception is thrown or not. The only time they wouldn't be executed is in the case of a severe runtime failure, such as a stack overflow, out of memory exception, or a crash in the runtime itself.

fs's Dispose() method will be invoked at the end of using's code block.

Yes, it will be disposed.
See the examples on the using Statement on MSDN - the Font is created with passed in parameters.

Related

Does "using" statement always dispose the object?

Does the using statement always dispose the object, even if there is a return or an exception is thrown inside it? I.E.:
using (var myClassInstance = new MyClass())
{
// ...
return;
}
or
using (var myClassInstance = new MyClass())
{
// ...
throw new UnexplainedAndAnnoyingException();
}
Yes, that's the whole point. It compiles down to:
SomeDisposableType obj = new SomeDisposableType();
try
{
// use obj
}
finally
{
if (obj != null)
((IDisposable)obj).Dispose();
}
Be careful about your terminology here; the object itself is not deallocated. The Dispose() method is called and, typically, unmanaged resources are released.
No it doesn't.
But that's not the fault of using statement though. It's because how the finally blocks are handled by CLR. There ARE some cases that finally blocks will not execute. If you have an unhandled exception and if the CLR thinks that executing more code will lead to more errors, it will not execute Dispose method (because it will not execute the finally block which Dispose method is compiled down to..). Therefore, be very careful and don't put your life into the execution of Dispose method.
The other cases which can cause Dispose method not being executed can be listed as:
Environment.FailFast
OutOfMemoryExceptionand StackOverflowException
Killing the process
Power loss
If the object implements IDisposable, it will be called.
From using Statement (C# Reference) by MSDN
Defines a scope, outside of which an object or objects will be
disposed.
The using statement allows the programmer to specify when objects that
use resources should release them. The object provided to the using
statement must implement the IDisposable interface. This interface
provides the Dispose method, which should release the object's
resources.

using and try finally, what should I choose

I have the following code block;
using (var msResp = new MemoryStream(Resp))
{
try
{
Response resp = new Response(msResp);
SetClientIdentityResponseValue sirv = new SetClientIdentityResponseValue(resp, (int)Response.Properties.Value);
if (!sirv.IsCredentialsValid)
{
throw new Exception("Authentication failed.");
}
if (sirv.IsSubscriptionExpired)
{
throw new Exception("Subscription expired.");
}
}
finally
{
msResp.Close();
}
}
I have read somewhere that a using statement automatically disposes the object.
Question:
Is using the Try/Finally combination redundant, when I already use the using statement?
Yes, it is redundant.
The using statement ensures that Dispose is called even if an
exception occurs while you are calling methods on the object. You can
achieve the same result by putting the object inside a try block and
then calling Dispose in a finally block; in fact, this is how the
using statement is translated by the compiler.
using Statement (C# Reference)
You don't need the finally. In fact, the using block is implemented internally using a try... finally.
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object.
http://msdn.microsoft.com/en-us/library/yh598w02.aspx
Its redundant. But remember, if you want to catch exception then you need a try-catch. using statement won't catch any exceptions. It just close and disposes the object.
Since you're calling Close rather than Dispose It's not blatantly obvious that the code is redundant.
The documentation for MemoryStream.Dispose indicates that the stream is closed when calling Dispose:
This method disposes the stream, by writing any changes to the backing store and closing the stream to release resources.
Which infers that Close is called. However, there's no harm in explicitly Closing the stream when you're done with it.
Bottom line: Is it redundant? Probably. Is it hurting anthing? Absolutely not. I'd prefer to be in the habit of cleaning up after myself, even if a janitor comes in behind me and has nothing to do (or cleans again).

Is IDisposeable Called if Un-Handled Exception is Encountered in a Using Statement?

If I have the following, will IDisposeable still be called on DisposeableObject, or will the object remain opened because an un-handled exception is encountered?
using ( DisposeableObject = new Object() )
{
throw new Exception("test");
}
A using is like wrapping your code in a try...finally and disposing in the finally, so yes, it should be called.
using expands to a try..finally block, so yes, it will call Dispose.
In the example you provided Dispose will be called before the exception is thrown.
The normal code for ensuring that dispose gets called looks like
var connection= new SqlConnection(connectionString);
try
{
// do something with the connection here
}
finally
{
connection.Dispose();
}
The usings statement replaces the need to write such a cumbersome statement.
using(var connection = new SqlConnection(connectionString))
{
// do something with the connection here
}
According to MSDN, yes. When control leaves the scope of the using statement, expect it to be disposed.
The object will be disposed as you will come out of scope when the exception bubbles up.
See: using Statement (C# Reference)
The using statement ensures that Dispose is called even if an exception occurs while you are calling methods on the object. You can achieve the same result by putting the object inside a try block and then calling Dispose in a finally block; in fact, this is how the using statement is translated by the compiler.

Is it better to use the [using] statement in C# or the [dispose] method? Does this apply to external (COM) objects?

What is better, the using directive, or the dispose directive when finished with an object?
using(FileStream fileStream = new FileStream(
"logs/myapp.log",
FileMode.Open,
FileAccess.Read,
FileShare.ReadWrite))
{
using(StreamReader streamReader = new StreamReader(fileStream))
{
this.textBoxLogs.Text = streamReader.ReadToEnd();
}
}
On the other hand, when I'm dealing with System.Net.Mail, I'm told I need to Dispose() of the object to release any stray locks.
Is there any consistent guidance? How do I tell what is more appropriate in a given situation for a given object?
The using statement (not directive) involves an implicit call to Dispose(), in a finally block. So there is no contradiction here. Can you link to that discussion?
The official definition of
using (x) { ... }
is
try ... finally if (x != null) x.Dispose(); }
What is better?
From a notational perspective, the using() { } block. Technically they are the same.
It's the same thing. Usage is simple, if you create the object and use it in only one method then use using. If you need to keep it alive beyond the method call then you have to use Dispose().
The runtime callable wrappers for COM objects don't have a Dispose() method.
There's no reason that I can think of to manually call Dispose(), other than in another implementation of Dispose() (for example in a class you've created that implements IDisposable) when you can wrap an object in a using block. The using block puts the creation and disposal of the object in a try/catch/finally block to pretty much gaurantee that the object will be disposed of correctly.
The compiler is more reliable than me. Or you. =)
MSDN documents the using statement and calls out where you can obtain the C# language specification where you can review section 8.13 "The using statement" (at least in the v4.0 reference it's 8.13) that gives a comprehensive explanation of the using statement and how to use it. The fifth paragraph gives the following:
A using statement is translated into
three parts: acquisition, usage, and
disposal. Usage of the resource is
implicitly enclosed in a try statement
that includes a finally clause. This
finally clause disposes of the
resource. If a null resource is
acquired, then no call to Dispose is
made, and no exception is thrown.
using(foo)
{
foo.DoStuff();
}
is just syntactic sugar for this:
try
{
foo.DoStuff();
}
finally
{
if(foo != null)
foo.Dispose();
}
So I'm not sure where the debate comes from. using blocks do call dispose. Most people prefer using blocks when possible as they are cleaner and clearer as to what is going on.
As long as the lifetime of the object is within a block of code, use using, if your object needs to be long lived, for example to be disposed after an asynchronous call you need to manually call Dispose.
A using block is way better than you of remembering the call to Dispose in all possible and impossible ways execution can leave a block of code.
using calls Dispose upon exit. using is better because it assures calling dispose.
using blocks automatically call Dispose() when the end of the block is reached.
There is one really important reason to use the "using statement" anywhere you can.
If the code that wrapped via using statement threw an exception, you could be sure that the "using object" would be disposed.

Curious C# using statement expansion

I've run ildasm to find that this:
using(Simple simp = new Simple())
{
Console.WriteLine("here");
}
generates IL code that is equivalent to this:
Simple simp = new Simple();
try
{
Console.WriteLine("here");
}
finally
{
if(simp != null)
{
simp.Dispose();
}
}
and the question is why the hell does it check null in the finally? The finally block will only be executed if the try block is executed, and the try block will only be executed if the Simple constructor succeeds (I.e. does not throw an exception), in which case simp will be non-null. (If there is some fear that some intervening steps might come between the Simple constructor and the beginning of the try block, then that would really be a problem because then an exception might be thrown that would prevent the finally block from executing at all.) So, why the hell?
Putting aside (please) the argument of whether the using statement is better than try-finally, I write my try-finally blocks as:
Simple simp = new Simple();
try
{
Console.WriteLine("here");
}
finally
{
simp.Dispose();
simp = null; // sanity-check in case I touch simp again
// because I don't rely on all classes
// necessarily throwing
// ObjectDisposedException
}
No, the finally block will ALWAYS be executed. You may not be getting the object from a new but from some other function that returns your object - and it might return NULL. using() is your friend!
dss539 was kind enough to suggest I include his note:
using(Simple simp = null)
is yet another reason that the expansion must check for null first.
using(Simple simp = null) is yet another reason that the expansion must check for null first.
MSDN on the using statement.
What I think is strange is that it doesn't expand to:
Simple simp = new Simple();
Simple __compilergeneratedtmpname = simp;
try
{
Console.WriteLine("here");
}
finally
{
if(__compilergeneratedtmpname != null)
{
__compilergeneratedtmpname.Dispose();
}
}
It appears that your comment:
"If there is some fear that some intervening steps might come between the Simple constructor and the beginning of the try block, then that would really be a problem because then an exception might be thrown that would prevent the finally block from executing at all."
is possibly dead on. See:
Atomicity & Asynchronous Exception Failures
I also want to note the issue(s) with WCF and using:
Avoiding Problems with the Using Statement and WCF Service Proxies which references:
Avoiding Problems with the Using Statement
The code must be translated this way to avoid possible NullReferenceException when disposing the object. As per C# language reference, the using statement accepts not only a local variable declaration as its first nonterminal resource_acquisition symbol, but any expression. Consider the following code:
DisposableType #object = null;
using(#object) {
// whatever
}
Clearly, unless null-conditional #object?.Dispose() in the finnaly block, an exception would ensue. The null check is superfluous only when the expression is of a non-nullable value type (non-nullable struct). And indeed, according to the aforementioned language reference it is absent in such case.

Categories