已经与其基础RCW分离的COM对象无法使用 – 为什么会发生?

我有时会遇到以下exception:无法使用已与其基础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值时会发生这种情况。 有谁知道可能是什么原因?

我发现当我处理AdEser创建的DirectoryEntry并且我仍在尝试使用AdUser对象时会发生此错误。 但是,上面发布的代码并非如此。 DirectoryEntry可能以某种方式处置自己吗?

当我尝试在许多活动目录对象上执行操作时,我也得到此exception。 例如,当我尝试为一千个用户设置SecurityDescriptor时,每200-300个用户就会收到此错误。 当我在建立新连接后重试操作时,我不会得到例外。 消息是检测到raceonrcwcleanup。 我的应用程序不是multithreading的。

任何帮助,将不胜感激。

是的,由于垃圾回收,可能会释放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) { } } 

然后我没有得到这些错误。 更多细节在这里: http : //directoryprogramming.net/forums/thread/7171.aspx