2

我正在使用System.DirectoryServices.AccountManagement.NET 4.5 创建帐户并在其上设置属性。其中一项要求是从模板帐户复制组成员身份(包括主组)。代码包括以下内容:

foreach (var group in userPrincipal.GetGroups()) {
    var groupPrincipal = (GroupPrincipal) @group;

    if (groupPrincipal.Sid != templatePrimaryGroup.Sid) {
        groupPrincipal.Members.Remove(userPrincipal);
        groupPrincipal.Save();
    }
}

这在大约 90% 的时间里都有效。其余时间,它失败了:

System.DirectoryServices.DirectoryServicesCOMException was unhandled HResult=-2147016656 Message=There is no such object on the server.

Source=System.DirectoryServices ErrorCode=-2147016656 ExtendedError=8333 ExtendedErrorMessage=0000208D: NameErr: DSID-03100213, problem 2001 (NO_OBJECT), data 0, best match of: 'OU=Whatever,DC=domain,DC=local`

GetGroups通话中。我的猜测是存在某种竞争条件,在我下次访问它之前没有完全创建用户。我从诊断日志中知道我每次都针对同一个域控制器(它使用的是相同的PrincipalContext,因此符合我的期望)所以这不是复制问题。

我的猜测准确吗?有没有好的方法来处理这个?我可以扔一个Sleep,但这似乎充其量是一种逃避,最坏的情况是脆弱。那么正确的做法是什么?

4

1 回答 1

1

尝试类似:

        int maxWait = 120;
        int cnt = 0;
        bool usable = false;

        while (usable == false && cnt < maxWait)
        {
            try
            {
                foreach (var group in userPrincipal.GetGroups())
                {
                    var groupPrincipal = (GroupPrincipal)@group;

                    if (groupPrincipal.Sid != templatePrimaryGroup.Sid)
                    {
                        groupPrincipal.Members.Remove(userPrincipal);
                        groupPrincipal.Save();
                    }
                }
                usable = true;
                break;
            }
            catch
            {
                System.Threading.Thread.Sleep(500);
            }
        }
        if (usable)
            //All okay
            ;
        else
            //Do something
            ;

这样你就可以尝试“一段时间”。如果它运行良好,如果没有,则执行诸如记录错误之类的操作,以便您稍后运行修复脚本。

于 2012-10-05T20:33:14.223 回答