title: Memory Leak when using PrincipalSearcher.FindAll()
body: <p>I too have a long running service using plugins and appdomains and am having a memory leak due to using directoryservices. Note that I am using system.directoryservices.accountmanagement but it is my understanding that it uses the same underlying ADSI API's and hence is prone to the same memory leaks.</p>
  
  <p>I've looked at all the CLR memory counters and the memory isn't being leaked there, and is all returned either on a forced GC or when I unload the appdomain. The leak is in private bytes which continually grow. I searched on here and have seen some issues related to a memory leak when using the ADSI API's but they seem to indicate that simply iterating over the directorysearcher fixes the problem. But as you can see in the code below, I am doing that in a foreach block and still the memory is being leaked. Any suggestions? Here is my method:</p>
  
  <pre><code>public override void JustGronkIT()
  {
      using (log4net.ThreadContext.Stacks["NDC"].Push(GetMyMethodName()))
      {
          Log.Info("Inside " + GetMyMethodName() + " Method.");
          System.Configuration.AppSettingsReader reader = new System.Configuration.AppSettingsReader();
          //PrincipalContext AD = null;
          using (PrincipalContext AD = new PrincipalContext(ContextType.Domain, (string)reader.GetValue("Domain", typeof(string))))
          {
              UserPrincipal u = new UserPrincipal(AD);
              u.Enabled = true;
              //u.Surname = "ju*";
              using (PrincipalSearcher ps = new PrincipalSearcher(u))
              {
                  myADUsers = new ADDataSet();
                  myADUsers.ADUsers.MinimumCapacity = 60000;
                  myADUsers.ADUsers.CaseSensitive = false;
                  foreach (UserPrincipal result in ps.FindAll())
                  {
                       myADUsers.ADUsers.AddADUsersRow(result.SamAccountName, result.GivenName, result.MiddleName, result.Surname, result.EmailAddress, result.VoiceTelephoneNumber,
                              result.UserPrincipalName, result.DistinguishedName, result.Description);
                   }
                   ps.Dispose();
              }
              Log.Info("Number of users: " + myADUsers.ADUsers.Count);
              AD.Dispose();
              u.Dispose();
          }//using AD
      }//Using log4net
  }//JustGronkIT
  </code></pre>
  
  <p>I made the following changes to the foreach loop and it's better but private bytes still grows and is never reclaimed.</p>
  
  <pre><code> foreach (UserPrincipal result in ps.FindAll())
   {
       using (result)
       {
           try
           {
               myADUsers.ADUsers.AddADUsersRow(result.SamAccountName, result.GivenName,           result.MiddleName, result.Surname, result.EmailAddress, result.VoiceTelephoneNumber,                                        result.UserPrincipalName, result.DistinguishedName, result.Description);
               result.Dispose();
           }
           catch
           {
               result.Dispose();
           }
       }
   }//foreach
  </code></pre>