c# - 使用 PrincipalSearcher.FindAll() 时发生内存泄漏

标签 c# .net directoryservices userprincipal principalcontext

我也有一个使用插件和应用程序域的长期运行服务,并且由于使用目录服务而导致内存泄漏。请注意,我使用的是 system.directoryservices.accountmanagement,但据我了解,它使用相同的底层 ADSI API,因此容易出现相同的内存泄漏。

我查看了所有 CLR 内存计数器,内存没有在那里泄漏,并且在强制 GC 或卸载应用程序域时全部返回。泄漏是在不断增长的私有(private)字节中。我在这里搜索并看到一些与使用 ADSI API 时的内存泄漏相关的问题,但它们似乎表明只需遍历目录搜索器即可解决问题。但正如您在下面的代码中看到的那样,我在 foreach block 中执行此操作,但内存仍在泄漏。有什么建议么?这是我的方法:

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

我对 foreach 循环进行了以下更改,它更好了,但私有(private)字节仍在增长并且永远不会被回收。

 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

最佳答案

我遇到了严重的内存泄漏,因为像你一样我写了类似...

                foreach (GroupPrincipal result in searcher.FindAll())
                {
                    results.Add(result.Name);
                }

但诀窍在于 FindAll 本身返回一个必须处理的对象...

            using (var searchResults = searcher.FindAll())
            {
                foreach (GroupPrincipal result in searchResults)
                {
                    results.Add(result.Name);
                }
            }

关于c# - 使用 PrincipalSearcher.FindAll() 时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11034265/

相关文章:

c# - 执行位于 JavaScript 代码隐藏中的函数?

c# - ASP.NET - AppDomain.CurrentDomain.GetAssemblies() - AppDomain 重启后程序集丢失

C# - 计算日期是否早于六个月

c# - 以正确格式将 Ajax 数据转换为 FLOT 图表?

powershell - 我应该使用 Active Directory 模块 cmdlet 还是 DirectoryServices .NET 类

c# - .Net (Windows Forms) 用户控件的点击事件

c# - .NET C# - WinForm 边框

c# - 无法等待进程运行直到结束

c# - 为什么在 Active Directory 中将用户的 "Primary Group"从 "Domain Users"更改为阻碍对用户的递归搜索?

c# - 批量获取AD自定义属性