473,387 Members | 1,700 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Is this pattern OK?

Hi Gurus,

Working with a .NET 2 C# web application. Using
System.DirectoryServices a lot to read information from AD. There
seemed to be several bugs in the .NET 1.1 implementation of that DLL
and out of habit I now very aggressively dispose of objects when I'm
done with them.

Is there anything wrong with this pattern:

DirectoryEntry objADAM = null;
DirectorySearcher objSearchADAM = null;
SearchResultCollection objSearchResults = null;

try
{
objADAM = new DirectoryEntry(ldap, admin, pass,
AuthenticationTypes.Secure);
objSearchADAM = new DirectorySearcher(objADAM);
objSearchResults = objSearchADAM.FindAll();

//Do something with the search results

objSearchResults.Dispose();
}
catch(Exception ex)
{
//Handle any errors
}
finally
{
objSearchADAM.Dispose();
objADAM.Dispose();
objSearchResults.Dispose();
}

The reason I ask is that this exact pattern exists in one of our web
applications that we recently updated from .NET 1.1. to .NET 2.0. In
the last week it has been randomly throwing null reference exceptions.
I cannot recreate what is causing the exception, but it can be
resolved by recycling the application in IIS. The only change to the
server in the last week is application of KB943485 and KB941644.

Looking at the stack trace indicates the null reference exception is
coming on the line:

objSearchResults.Dispose();

Within the finally{} block. So I assume I should either remove the
first call to Dispose(), and have everything in the finally{} block or
change the finally{} block to something like:

if(objSearchResults != null)
objSearchResults.Dispose();

The thing I can't work out is why this only started happening in the
last week!

Many thanks for any advice, Richard
Jan 18 '08 #1
10 1212
On Fri, 18 Jan 2008 08:57:50 -0800, ri****************@eshareuk.com
<ri****************@eshareuk.comwrote:
[...]
Looking at the stack trace indicates the null reference exception is
coming on the line:

objSearchResults.Dispose();
Is the variable "objSearchResults" null when you try to execute that line?

If so, then I'd say yes...there's something wrong with this "pattern",
_somewhere_. You shouldn't be calling methods on null references, not
even Dispose().

Now, I don't see anything in the docs for DirectorySearcher.FindAll() that
suggests it should ever return a null value. So, if the exception had
been on the first instance of that line, within the "try" part of your
code, that would have seemed like a bug in the DirectorySearcher class.

However, since it's in the "finally" part of your code, then I suspect
you're getting an exception before the variable can be initialized to a
non-null value, and so of course you get an exception when you try to call
Dispose() on the null reference.
Within the finally{} block. So I assume I should either remove the
first call to Dispose(), and have everything in the finally{} block or
change the finally{} block to something like:

if(objSearchResults != null)
objSearchResults.Dispose();
You should remove the first call to Dispose() _and_ change the "finally"
block to check the variable's value for null before calling Dispose().
You should similarly check _all_ of your objects for null before calling
Dispose() on them, since you have no way to guarantee that they are
non-null when entering the "finally" block.
The thing I can't work out is why this only started happening in the
last week!
Sounds like you're getting a new exception that didn't happen before. The
bug was always in the code, but you just never hit it. As for what the
exception might be and why it's just now starting to happen, who knows?
You may just have been lucky, or it may be that some update to the system
has changed the behavior slightly, or it could be something else.

But the code was wrong in the first place, so the first thing to do is fix
it.

Pete
Jan 18 '08 #2

<ri****************@eshareuk.comwrote in message
news:8b**********************************@h11g2000 prf.googlegroups.com...
Hi Gurus,

Working with a .NET 2 C# web application. Using
System.DirectoryServices a lot to read information from AD. There
seemed to be several bugs in the .NET 1.1 implementation of that DLL
and out of habit I now very aggressively dispose of objects when I'm
done with them.

Is there anything wrong with this pattern:

DirectoryEntry objADAM = null;
DirectorySearcher objSearchADAM = null;
SearchResultCollection objSearchResults = null;

try
{
objADAM = new DirectoryEntry(ldap, admin, pass,
AuthenticationTypes.Secure);
objSearchADAM = new DirectorySearcher(objADAM);
objSearchResults = objSearchADAM.FindAll();

//Do something with the search results

objSearchResults.Dispose();
}
catch(Exception ex)
{
//Handle any errors
}
finally
{
objSearchADAM.Dispose();
objADAM.Dispose();
objSearchResults.Dispose();
}

The reason I ask is that this exact pattern exists in one of our web
applications that we recently updated from .NET 1.1. to .NET 2.0. In
the last week it has been randomly throwing null reference exceptions.
I cannot recreate what is causing the exception, but it can be
resolved by recycling the application in IIS. The only change to the
server in the last week is application of KB943485 and KB941644.

Looking at the stack trace indicates the null reference exception is
coming on the line:

objSearchResults.Dispose();

Within the finally{} block. So I assume I should either remove the
first call to Dispose(), and have everything in the finally{} block or
change the finally{} block to something like:

if(objSearchResults != null)
objSearchResults.Dispose();
What you ought to do instead is convert try / finally { Dispose(); } into
using blocks, which automatically handle the null case.
>
The thing I can't work out is why this only started happening in the
last week!

Many thanks for any advice, Richard

Jan 18 '08 #3
On Jan 18, 1:58 pm, "Ben Voigt [C++ MVP]" <r...@nospam.nospamwrote:
<richard.markiew...@eshareuk.comwrote in message

news:8b**********************************@h11g2000 prf.googlegroups.com...
Hi Gurus,
Working with a .NET 2 C# web application. Using
System.DirectoryServices a lot to read information from AD. There
seemed to be several bugs in the .NET 1.1 implementation of that DLL
and out of habit I now very aggressively dispose of objects when I'm
done with them.
Is there anything wrong with this pattern:
DirectoryEntry objADAM = null;
DirectorySearcher objSearchADAM = null;
SearchResultCollection objSearchResults = null;
try
{
objADAM = new DirectoryEntry(ldap, admin, pass,
AuthenticationTypes.Secure);
objSearchADAM = new DirectorySearcher(objADAM);
objSearchResults = objSearchADAM.FindAll();
//Do something with the search results
objSearchResults.Dispose();
}
catch(Exception ex)
{
//Handle any errors
}
finally
{
objSearchADAM.Dispose();
objADAM.Dispose();
objSearchResults.Dispose();
}
The reason I ask is that this exact pattern exists in one of our web
applications that we recently updated from .NET 1.1. to .NET 2.0. In
the last week it has been randomly throwing null reference exceptions.
I cannot recreate what is causing the exception, but it can be
resolved by recycling the application in IIS. The only change to the
server in the last week is application of KB943485 and KB941644.
Looking at the stack trace indicates the null reference exception is
coming on the line:
objSearchResults.Dispose();
Within the finally{} block. So I assume I should either remove the
first call to Dispose(), and have everything in the finally{} block or
change the finally{} block to something like:
if(objSearchResults != null)
objSearchResults.Dispose();

What you ought to do instead is convert try / finally { Dispose(); } into
using blocks, which automatically handle the null case.
The thing I can't work out is why this only started happening in the
last week!
Many thanks for any advice, Richard
Thank you both for your input Pete and Ben.

What I have done is go ahead as Ben suggested and just replaced the
finally{} block with a using statement on all my DirectoryEntries,
DirectorySearchers and SearchResultCollections. It's certainly easier
to see what's going on that way.

Hopefully this will resolve the issue :)

I see that even for the latest versions of the Framework, MS still
say:

"Due to implementation restrictions, the SearchResultCollection class
cannot release all of its unmanaged resources when it is garbage
collected. To prevent a memory leak, you must call the Dispose method
when the SearchResultCollection object is no longer needed."

This is presumably something to do with the COM stuff going on behind
the scenes.

Can one of you confirm that if my code looks like this:

try
{
using(DirectoryEntry objADAM = new DirectoryEntry(ldap, admin,
pass, AuthenticationTypes.Secure)
{
using(DirectorySearcher objSearchADAM = new
DirectorySearcher(objADAM)
{
using(SearchResultCollection objSearchResults =
objSearchADAM.FindAll())
{
//Do something with the search results
}
}
}
}
catch(Exception ex)
{
//Handle the error
}

That if my AD code hits a problem inside the try{}, all my directory
objects will be disposed? This is the correct pattern for implementing
Using{} in this scenario?

Many thanks again for your help

Richard
Jan 18 '08 #4
Ben Voigt [C++ MVP] <rb*@nospam.nospamwrote:

<snip>
What you ought to do instead is convert try / finally { Dispose(); } into
using blocks, which automatically handle the null case.
They also cope with the possibility of Dispose calls throwing
exceptions - with a single finally block, if an early Dispose call
fails, the rest won't get executed.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Jan 18 '08 #5
On Fri, 18 Jan 2008 11:20:21 -0800, ri****************@eshareuk.com
<ri****************@eshareuk.comwrote:
Can one of you confirm that if my code looks like this:

try
{
using(DirectoryEntry objADAM = new DirectoryEntry(ldap, admin,
pass, AuthenticationTypes.Secure)
{
using(DirectorySearcher objSearchADAM = new
DirectorySearcher(objADAM)
{
using(SearchResultCollection objSearchResults =
objSearchADAM.FindAll())
{
//Do something with the search results
}
}
}
}
catch(Exception ex)
{
//Handle the error
}

That if my AD code hits a problem inside the try{}, all my directory
objects will be disposed? This is the correct pattern for implementing
Using{} in this scenario?
Yes, that will work fine (not counting the missing parens, which the
compiler would tell you about :) ). Though you can clean up the
formatting a bit by putting braces only around the last "using" block and
not indenting the second or third "using":

using(DirectoryEntry objADAM = new DirectoryEntry(ldap, admin, pass,
AuthenticationTypes.Secure))
using(DirectorySearcher objSearchADAM = new
DirectorySearcher(objADAM))
using(SearchResultCollection objSearchResults =
objSearchADAM.FindAll())
{
//Do something with the search results
}

It violates the usual indentation conventions, but is a common variation
and IMHO looks nicer.

Pete
Jan 18 '08 #6
On Jan 18, 2:32 pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Ben Voigt [C++ MVP] <r...@nospam.nospamwrote:

<snip>
What you ought to do instead is convert try / finally { Dispose(); } into
using blocks, which automatically handle the null case.

They also cope with the possibility of Dispose calls throwing
exceptions - with a single finally block, if an early Dispose call
fails, the rest won't get executed.

--
Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
World class .NET training in the UK:http://iterativetraining.co.uk
Thank you Jon.

So what you are saying is, if my original snippet looked like this:

finally
{
objSearchResults.Dispose(); //The troublesome line is now first in the
finally block
objSearchADAM.Dispose();
objADAM.Dispose();
}

That the second and third dispose statements would not be executed
after the first one threw an exception?

Do you know what Using{} does behind the scenes? Does it create a
try{} finally{} on the objects I "use"?

We had a lot of problems with System.DirectoryServices in .NET 1.1
where objects weren't disposed properly, and I'm keen not to go down
that route again. So it would be good to know that my revised pattern
is not subject to the same problem.

Many thanks, Richard
Jan 18 '08 #7
On Fri, 18 Jan 2008 11:50:43 -0800, ri****************@eshareuk.com
<ri****************@eshareuk.comwrote:
So what you are saying is, if my original snippet looked like this:

finally
{
objSearchResults.Dispose(); //The troublesome line is now first in the
finally block
objSearchADAM.Dispose();
objADAM.Dispose();
}

That the second and third dispose statements would not be executed
after the first one threw an exception?
Yes. That said, you should of course not have your own code have bugs
that throw exceptions, and IMHO the Dispose() method should never throw an
exception. But the "using" statement provides the "belts and suspenders"
to ensure that even if those rules are violated, things get cleaned up.
Do you know what Using{} does behind the scenes? Does it create a
try{} finally{} on the objects I "use"?
Yes. The "using" statement is essentially equivalent to:

IDisposable obj = // whatever your variable is;

try
{
// code in the using block
}
finally
{
obj.Dispose();
}

Nested "using" statements nest the whole thing:

IDisposable obj1 = ...;

try
{
IDisposeable obj2 = ...;

try
{
// code in the using block
}
finally
{
obj2.Dispose();
}
}
finally
{
obj1.Dispose();
}

Thus even if an inner call to Dispose() throws an exception, the outer
ones still get executed.

Note also that the "using" statement essentially generates a private
variable that it uses for the call to Dispose(). It doesn't matter what
you do to the actual declared variable in your own code, the "using"
statement will always call Dispose() on the original reference.

Pete
Jan 18 '08 #8
On Jan 18, 3:08 pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Fri, 18 Jan 2008 11:50:43 -0800, richard.markiew...@eshareuk.com

<richard.markiew...@eshareuk.comwrote:
So what you are saying is, if my original snippet looked like this:
finally
{
objSearchResults.Dispose(); //The troublesome line is now first in the
finally block
objSearchADAM.Dispose();
objADAM.Dispose();
}
That the second and third dispose statements would not be executed
after the first one threw an exception?

Yes. That said, you should of course not have your own code have bugs
that throw exceptions, and IMHO the Dispose() method should never throw an
exception. But the "using" statement provides the "belts and suspenders"
to ensure that even if those rules are violated, things get cleaned up.
Do you know what Using{} does behind the scenes? Does it create a
try{} finally{} on the objects I "use"?

Yes. The "using" statement is essentially equivalent to:

IDisposable obj = // whatever your variable is;

try
{
// code in the using block
}
finally
{
obj.Dispose();
}

Nested "using" statements nest the whole thing:

IDisposable obj1 = ...;

try
{
IDisposeable obj2 = ...;

try
{
// code in the using block
}
finally
{
obj2.Dispose();
}
}
finally
{
obj1.Dispose();
}

Thus even if an inner call to Dispose() throws an exception, the outer
ones still get executed.

Note also that the "using" statement essentially generates a private
variable that it uses for the call to Dispose(). It doesn't matter what
you do to the actual declared variable in your own code, the "using"
statement will always call Dispose() on the original reference.

Pete
Thank you Pete for taking the time to explain so clearly.

All the best, Richard
Jan 18 '08 #9
Peter Duniho <Np*********@nnowslpianmk.comwrote:

<snip>
Yes. The "using" statement is essentially equivalent to:

IDisposable obj = // whatever your variable is;

try
{
// code in the using block
}
finally
{
obj.Dispose();
}
One extra benefit - the finally block is actually:

finally
{
if (obj != null)
{
obj.Dispose();
}
}

In other words, it doesn't matter if the expression you use for the
using statement returns null.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Jan 18 '08 #10
On Jan 18, 3:27 pm, Jon Skeet [C# MVP] <sk...@pobox.comwrote:
Peter Duniho <NpOeStPe...@nnowslpianmk.comwrote:

<snip>
Yes. The "using" statement is essentially equivalent to:
IDisposable obj = // whatever your variable is;
try
{
// code in the using block
}
finally
{
obj.Dispose();
}

One extra benefit - the finally block is actually:

finally
{
if (obj != null)
{
obj.Dispose();
}

}

In other words, it doesn't matter if the expression you use for the
using statement returns null.

--
Jon Skeet - <sk...@pobox.com>http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
World class .NET training in the UK:http://iterativetraining.co.uk
Great stuff. Thank you Jon.

All the best

Richard
Jan 18 '08 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: gsv2com | last post by:
One of my weaknesses has always been pattern matching. Something I definitely need to study up on and maybe you guys can give me a pointer here. I'm looking to remove all of this code and just...
0
by: Andy Read | last post by:
Hello all, I have the requirement to produce source code that produces an object hierarchy. Example: Root | Folder 1
11
by: FluffyCat | last post by:
In Febraury - April of 2002 I put together in Java examples of all 23 of the classic "Gang Of Four" design patterns for my website. Partly I wanted to get a better understanding of those patterns....
1
by: Sea Sharper | last post by:
Hi, C#, from a FileSystemWatcher I would like to catch all files with a *.* filter but then inside the event handler compare against a list of wildcards (eg '*.abc;*.def') Is there anywhere...
12
by: FluffyCat | last post by:
New on November 28, 2005 for www.FluffyCat.com PHP 5 Design Pattern Examples - the Visitor Pattern. In the Visitor pattern, one class calls a function in another class and passes an instance of...
1
by: ltruett | last post by:
Last week I continued my series of design patterns examples using PHP 5 with the Bridge Pattern, Flyweight Pattern, and Proxy Pattern. Here now is my 20th PHP 5 design pattern example, the...
34
by: Steven Nagy | last post by:
So I was needing some extra power from my enums and implemented the typesafe enum pattern. And it got me to thinking... why should I EVER use standard enums? There's now a nice little code...
11
by: td0g03 | last post by:
Hello, I just have a few questions. The first one be how would you print a pattern. I could use the if else, but I remember my teacher talking about something like for(i=1;i<=size;i) ...
1
by: halekio | last post by:
Hi all, Please bear with me as I've only started programming in C# 2 weeks ago and this is my first contact with OOP. I ran into a situation where I needed to catch an event in an object that...
19
by: konrad Krupa | last post by:
I'm not expert in Pattern Matching and it would take me a while to come up with the syntax for what I'm trying to do. I hope there are some experts that can help me. I'm trying to match...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.