Reputation: 55
I'm aware of technique to handle IDisposable in a traditional manner. Say, in OnStop() method of windows service I close message queue client:
if (client != null)
{
client.Dispose();
}
For the first time today I saw one guy doing that this way:
using (client)
{
client = null;
}
What is exactly happening inside his "using" or does he dispose correctly at all?
Upvotes: 5
Views: 232
Reputation: 81277
If the scope of "client" extends outside the "using" block, as it would appear to, the code as written will ensure that "client" gets disposed before control leaves the "using" block, and the reference to the newly-defunct "client" object will be destroyed. Nulling out the reference to it may be important if it's a field, and may be critical if it's a property that attaches events.
My guess would be that "client" is a field or property, and that the author of the "using" code thought it was more concise than the version given by Marc Gravell. I would grant the author that the code is concise, but would suggest that even more concise and clearer would be to define a generic "Zap" routine which accepts an IDisposable by reference, uses Interlocked.Exchange to read and null it, and disposes it if it wasn't null. In that case, the "using" statement would be replaced with:
Zap(ref client);
which has the benefit of being more concise while almost certainly being clearer.
Upvotes: 0
Reputation: 1064044
Your using
-based colleague's code will work, but is arguably overkill;
using(client) {
client = null;
}
is essentially:
{ // scope here to denote that 'tmp' is not defined outside this scope
var tmp = client;
try {
client = null;
} finally {
if(tmp != null) tmp.Dispose();
}
}
(not quite that in all cases, as there are value-types and explicit interface implementation to think about).
Personally, I'd just use using
for the whole thing where possible (i.e. in the code that initially allocates client).
One time I might use this is a lazy:
using(client as IDisposable) { client = null; } // dispose if needed
i.e. client
is something outside my control, and I'm not sure if it implements IDisposable
or not, but if it does, I need to release it.
Upvotes: 4
Reputation: 318
To me it looks not effective at all. Since the client is set to null the using has nothing referenced to dispose anymore, even though the actual object is still in memory, just not referenced by any variable (it will be garbage collected later on, but what's the point of the using then?).
Upvotes: 0
Reputation: 273711
The using(){}
statement grabs a copy of the reference var so this assignment with null
is ineffective.
Upvotes: 6
Reputation: 57593
Exiting from
using (client)
{
}
client.Dispose()
is called automatically for you.
client = null
should be called out of that code in my opinion.
Remember that to use using(object)
the object should implement IDisposable
interface.
Upvotes: 3