Reputation: 19
I am using DirectorySearcher in a using statement to loop through about 5000 objects. It appears through troubleshooting that the PropertiesToLoad property is causing a massive memory leak. My program goes from 0 to 2 GB of memory used in no time flat if I set the propertiesToLoad property on each object. In this manner the search is very fast but has the memory leak.
If I set the PropertiesToLoad at the beginning and not on each loop the memory leak does not occur but the search is slow. I have tried clearing the Properties on each loop which fixes the memory leak but again causes the search to slowdown. I am hoping to find the best of both worlds here.
NOTE: My app is Multi-Threaded so the AD search is happening on 10 threads at once.
using (DirectorySearcher mySearcher = new DirectorySearcher(new DirectoryEntry("LDAP://rootDSE", null, null, AuthenticationTypes.FastBind)))
{
try
{
mySearcher.Filter = ("(&(objectClass=user)(sAMAccountName=" + object + "))");
mySearcher.SearchScope = SearchScope.Subtree;
mySearcher.CacheResults = false;
mySearcher.PropertiesToLoad.AddRange(new string[] { "canonicalName", "displayName", "userAccountControl" });
foreach (SearchResult result in mySearcher.FindAll())
{
try
{
shareInfo.displayname = result.Properties["displayName"][0].ToString();
}
catch
{
shareInfo.displayname = "N/A";
}
shareInfo.canName = result.Properties["canonicalName"][0].ToString();
int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
bool disabled = ((userAccountControl & 2) > 0);
if (disabled == true)
shareInfo.acctstatus = "Disabled";
else
shareInfo.acctstatus = "Enabled";
}
}
catch
{
}
}
Upvotes: 0
Views: 537
Reputation: 40998
Here's something I learned just a few weeks ago from the documentation for the FindAll
method:
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.
You're using using
on the DirectorySearcher
, but not on the result collection. Try assigning the resulting collection to a variable that can be disposed later:
using (var results = mySearcher.FindAll())
{
foreach (SearchResult result in results)
{
...
}
}
Upvotes: 4