C# 无法使用与其基础RCW分离的COM对象-为什么会发生这种情况?

C# 无法使用与其基础RCW分离的COM对象-为什么会发生这种情况?,c#,.net,com,interop,active-directory,C#,.net,Com,Interop,Active Directory,我有时会遇到以下例外情况: 无法使用已与其基础RCW分离的COM对象 示例代码: using (AdOrganizationalUnit organizationalUnit = new AdOrganizationalUnit(ADHelper.GetDirectoryEntry(ouAdDn))) { using (AdUser user = organizationalUnit.AddUser(commonName)) { //set some properties user.P

我有时会遇到以下例外情况: 无法使用已与其基础RCW分离的COM对象

示例代码:

using (AdOrganizationalUnit organizationalUnit = new AdOrganizationalUnit(ADHelper.GetDirectoryEntry(ouAdDn))) 
{ 
using (AdUser user = organizationalUnit.AddUser(commonName)) 
{ 
//set some properties 
user.Properties[key].Add(value); 

user.CommitChanges(); 

user.SetPassword(password); //it is set using Invoke 

//must be set after creating user 
user.Properties["UserAccountControl"].Value = 512; 

user.CommitChanges(); 

} 
} 
AdUser看起来像这样:

public class AdUser : DirectoryEntry 
{ 
public AdUser(DirectoryEntry entry) 
: base(entry.NativeObject) 
{ 
} 

public bool SetPassword(string password) 
{ 
object result = this.Invoke("SetPassword", new object[] { password }); 
return true; 
} 
} 
这是我的代码的简化版本。异常有时出现,有时不出现。大多数情况下,当我试图设置UserAccountControl值时会发生这种情况。 有人知道原因是什么吗

我发现这个错误发生在我处理创建AdUser时使用的DirectoryEntry时,并且我仍在尝试使用AdUser对象。然而,在上面发布的代码中,情况并非如此。DirectoryEntry是否可能以某种方式自行处置

当我尝试在许多active directory对象上执行操作时,也会出现此异常。例如,当我尝试为1000个用户设置SecurityDescriptor时,每200-300个用户就会出现一个错误。当我在建立新连接后重试该操作时,我没有得到异常。检测到消息为raceonrcwcleanup。我的应用程序不是多线程的


任何帮助都将不胜感激。

是的,DirectoryEntry对象可能由于垃圾收集而被释放。GC在其自己的线程中运行,因此可以在RCW清理上进行竞争

尝试在AdUser对象中保存对它的引用。也就是说,它应该看起来像

public class AdUser : DirectoryEntry 
{ 
  DirectoryEntry entry;
    public AdUser(DirectoryEntry entry) : base(entry.NativeObject) 
    { 
      this.entry = entry;
    } 
    ...
}

问题似乎是由于在AdUser中从NativeObject创建DirectoryEntry引起的。 当我把AdUser从:

public class AdUser : DirectoryEntry 
{ 
public AdUser(DirectoryEntry entry) 
: base(entry.NativeObject) 
{ 
} 
} 
并创建了将DirectoryEntry视为组件的包装器:

public class ActiveDirectoryObject : IDisposable 
{ 
private bool disposed; 
public DirectoryEntry Entry { get; protected set; } 

public ActiveDirectoryObject(DirectoryEntry entry) 
{ 
Entry = entry; 
} 

public void CommitChanges() 
{ 
Entry.CommitChanges(); 
} 

public void Dispose() 
{ 
Dispose(true); 
GC.SuppressFinalize(this); 
} 

private void Dispose(bool disposing) 
{ 
if (!this.disposed) 
{ 
if (disposing) 
{ 
if (Entry != null) Entry.Dispose(); 
} 
disposed = true; 
} 
} 
} 

public class AdUser : ActiveDirectoryObject 
{ 
public AdUser(DirectoryEntry entry) 
: base(entry) 
{ 
} 
} 
那么我就不会犯这些错误了。
此处的更多详细信息:

很抱歉没有响应,我尝试使用DirectoryEntry作为组件,目前它工作正常。更多详细信息:@empi:你应该从你提到的帖子中复制答案,并将其作为asnwer添加到你自己的问题中。然后把它作为答案。这将有助于其他人在这里寻找答案。当你只是在评论中发布一个链接时,它就不那么明显了…+1用于解决你自己的问题,发布解决方案,更重要的是解决我来这里的问题。