处置在 DirectorySearcher 中未按预期工作

发布于 2024-11-15 17:55:40 字数 1104 浏览 0 评论 0原文

我正在尝试连接并执行简单的功能,例如使用 C# 在 Active Directory 上进行搜索。但是,我遇到了一个问题。我正在使用 DirectorySearcher 来搜索目录。目录中有大量条目。

这是函数

void RunThis()
{
        DirectoryEntry de = new DirectoryEntry();
        de.Path = "LDAP://" + domainName;
        de.Username = username;
        de.Password = password;
        de.AuthenticationType = AuthenticationTypes.Secure;

        DirectorySearcher deSearch = new DirectorySearcher(de);
        //Skipping properties to load
        try
        {
            deSearch.SearchScope = SearchScope.Subtree;
            SearchResultCollection rescoll = deSearch.FindAll();
            deSearch.Dispose();
            rescoll.Dispose();
        }
        catch (Exception obj)
        {
            System.Console.WriteLine("Exception in getting results. {0}",obj.Message);
        }

     }
     de.Dispose();

} // end of function 

这是我精简后的示例函数。我可以找到很多帖子说显式调用 DirectorySearcher 或 ResultCollection 对象的 dispose 将解决问题。

然而,我看到任务使用的内存在不断增加。代码的其他部分没有太多其他内容。当我注释该函数时,内存使用量变得稳定。

还有其他人遇到过这个问题并找到解决方案吗?

PS:而且没有出路。我需要做 findall :(

I am trying to connect and do simple functionalities such as search on an Active Directory using C#. However, I am stuck in a problem. I am using DirectorySearcher to search the directory. There are loads of entries in the directory.

This is the function

void RunThis()
{
        DirectoryEntry de = new DirectoryEntry();
        de.Path = "LDAP://" + domainName;
        de.Username = username;
        de.Password = password;
        de.AuthenticationType = AuthenticationTypes.Secure;

        DirectorySearcher deSearch = new DirectorySearcher(de);
        //Skipping properties to load
        try
        {
            deSearch.SearchScope = SearchScope.Subtree;
            SearchResultCollection rescoll = deSearch.FindAll();
            deSearch.Dispose();
            rescoll.Dispose();
        }
        catch (Exception obj)
        {
            System.Console.WriteLine("Exception in getting results. {0}",obj.Message);
        }

     }
     de.Dispose();

} // end of function 

This is a sample function I trimmed down to. I could find a lot of posts which said that calling dispose explicitly of the DirectorySearcher or ResultCollection object will solve the problem.

However, I see that the memory used by the task is increasing constantly. There isnt much else going in the other part of the code. When i comment the function, the memory usage becomes stable.

Has anyone else faced the issue and found a solution?

PS: And there is no way out. I need to do the findall :(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

故乡的云 2024-11-22 17:55:40

如果抛出异常,您并不会处理所有内容:您需要使用 try/finally 块或等效的 using 语句,例如:

void RunThis()
{
    using (DirectoryEntry de = new DirectoryEntry())
    {
        de.Path = "LDAP://" + domainName;
        de.Username = username;
        de.Password = password;
        de.AuthenticationType = AuthenticationTypes.Secure;

        using (DirectorySearcher deSearch = new DirectorySearcher(de))
        {
            deSearch.SearchScope = SearchScope.Subtree;
            using (SearchResultCollection rescoll = deSearch.FindAll())
            {
            }
        }
    }

} // end of function 

You aren't disposing everything if an exception is thrown: you need to use a try/finally block or the equivalent using statement, something like:

void RunThis()
{
    using (DirectoryEntry de = new DirectoryEntry())
    {
        de.Path = "LDAP://" + domainName;
        de.Username = username;
        de.Password = password;
        de.AuthenticationType = AuthenticationTypes.Secure;

        using (DirectorySearcher deSearch = new DirectorySearcher(de))
        {
            deSearch.SearchScope = SearchScope.Subtree;
            using (SearchResultCollection rescoll = deSearch.FindAll())
            {
            }
        }
    }

} // end of function 
ぶ宁プ宁ぶ 2024-11-22 17:55:40

首先,您需要确定泄漏的是托管内存还是非托管内存。

  1. 使用 perfmon 查看进程“.net 内存# 所有堆中的字节数”和 Process\Private Bytes 发生了什么情况。比较数字,记忆力就会上升。如果专用字节的增长速度超过了堆内存的增长速度,则为非托管内存增长。

  2. 非托管内存增长将指向未释放的对象(但最终在其终结器执行时被收集)。

  3. 如果是托管内存增长,那么我们需要查看哪一代/LOH(每一代堆字节也有性能计数器)。

  4. 如果是大对象堆字节,您将需要重新考虑大字节数组的使用和丢弃。也许字节数组可以被重新使用而不是被丢弃。另外,请考虑分配 2 的幂的大字节数组。这样,在处理时,您将在大对象堆中留下一个大“洞”,可以由另一个相同大小的对象填充。

  5. 最后一个问题是固定内存,但我对此没有任何建议,因为我从来没有搞乱过它。

First, you need to figure out whether it is managed or unmanaged memory that is leaking.

  1. Use perfmon to see what happens to your process '.net memory# Bytes in all Heaps' and Process\Private Bytes. Compare the numbers and the memory rises. If the rise in Private bytes outpaces the rise in heap memory, then it's unmanaged memory growth.

  2. Unmanaged memory growth would point to objects that are not being disposed (but eventually collected when their finalizer executes).

  3. If it's managed memory growth, then we'll need to see which generation/LOH (there are also performance counters for each generation of heap bytes).

  4. If it's Large Object Heap bytes, you'll want to reconsider the use and throwing away of large byte arrays. Perhaps the byte arrays can be re-used instead of discarded. Also, consider allocating large byte arrays that are powers of 2. This way, when disposed, you'll leave a large "hole" in the large object heap that can be filled by another object of the same size.

  5. A final concern is pinned memory, but I don't have any advice for you on this because I haven't ever messed with it.

很快妥协 2024-11-22 17:55:40

DirectoryEntry 和 DirectorySearcher 都实现 IDisposable。此外,您还需要确保即使发生异常也能处理它们。我建议将两者的构造放在使用块内。

编辑:与SearchResultCollection一样,所以+1给@Joe。

DirectoryEntry and DirectorySearcher both implement IDisposable. Also, you need to insure that they are disposed even in the event of an exception. I would suggest placing the construction of both inside using blocks.

EDIT: As does SearchResultCollection, so +1 to @Joe.

深白境迁sunset 2024-11-22 17:55:40

尝试使用 using 语句来代替。

void RunThis()
{
        using(DirectoryEntry de = new DirectoryEntry())
        {
          de.Path = "LDAP://" + domainName;
          de.Username = username;
          de.Password = password;
          de.AuthenticationType = AuthenticationTypes.Secure;

          DirectorySearcher deSearch = new DirectorySearcher(de);
          //Skipping properties to load
          try
          {
            deSearch.SearchScope = SearchScope.Subtree;
            SearchResultCollection rescoll = deSearch.FindAll();
            deSearch.Dispose();
            rescoll.Dispose();
          }
          catch (Exception obj)
          {
            System.Console.WriteLine("Exception in getting results. {0}",obj.Message);
          }
        }
}

这不仅会处理 DirectoryEntry,还会为您清理 using 块中的其他所有内容。

Try using a using statement instead

void RunThis()
{
        using(DirectoryEntry de = new DirectoryEntry())
        {
          de.Path = "LDAP://" + domainName;
          de.Username = username;
          de.Password = password;
          de.AuthenticationType = AuthenticationTypes.Secure;

          DirectorySearcher deSearch = new DirectorySearcher(de);
          //Skipping properties to load
          try
          {
            deSearch.SearchScope = SearchScope.Subtree;
            SearchResultCollection rescoll = deSearch.FindAll();
            deSearch.Dispose();
            rescoll.Dispose();
          }
          catch (Exception obj)
          {
            System.Console.WriteLine("Exception in getting results. {0}",obj.Message);
          }
        }
}

This will not only dispose of the DirectoryEntry but will also clean up everything else in the using block for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文