为什么要花10个小时才能返回DirectoryEntry属性?

本文关键字:返回 DirectoryEntry 属性 10个 小时 为什么 | 更新日期: 2023-09-27 18:17:24

我们在一个测试AD中枚举数千个用户。整个过程大约需要一个小时。但有时,对于单个用户,以下几行代码将卡住大约10个小时。

这并不总是发生,当它发生时,它可能发生在任何AD用户。

        using (DirectoryEntry de = new DirectoryEntry(String.Format(@"LDAP://{0}/<GUID={1}>", host, objectGUID), admin, password, server.AuthenticationMethod))
        {
            try
            {
                dn = (string)de.Properties["distinguishedName"][0];
            }
            catch
            {
                // log it...
            }
        }

经过长时间的拖延,一切照常进行。

是什么导致了这个延迟?

为什么要花10个小时才能返回DirectoryEntry属性?

TL;DR启用AuthenticationTypes。

我创建了一个测试应用程序,它能够根据需要重现这个问题。测试应用程序所做的只是启动4个线程,每个线程包含一个无限while循环。在while循环中,我创建了一个新的DirectoryEntry,并在其上调用RefreshCache。通常,特别是在启动时,其中一个线程会遇到以下异常

COMException -2147016643 "A decoding error has occurred."

此错误也称为0x8007203D aka -2147016643 aka 2147950653

当在一个线程中看到此异常时,一个或多个其他线程将挂起对RefreshCache的调用。

在DirectoryEntry构造函数中,我们没有包含AuthenticationTypes.Secure。Secure是默认标志,但是因为我们设置了其他AuthenticationTypes标志,所以我们也应该手动包含Secure。不知道为什么,但是当启用安全模式时,DirectoryServices在多线程下表现得更好。