我有时会遇到以下异常: 无法使用已与其基础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可能以某种方式处置自己吗?
当我尝试对许多活动目录对象执行操作时,我也会遇到此异常。例如,当我尝试为一千个用户设置SecurityDescriptor时,每200-300个用户就会收到此错误。当我在建立新连接后重试操作时,我不会得到例外。消息是检测到raceonrcwcleanup。我的应用程序不是多线程的。
任何帮助都将不胜感激。
答案 0 :(得分:3)
是的,由于垃圾回收,可能会丢弃DirectoryEntry对象。 GC正在自己的线程中运行,因此可以在RCW清理上进行竞争。
尝试在AdUser对象中保存对它的引用。即它看起来应该是
public class AdUser : DirectoryEntry
{
DirectoryEntry entry;
public AdUser(DirectoryEntry entry) : base(entry.NativeObject)
{
this.entry = entry;
}
...
}
答案 1 :(得分:2)
似乎问题是由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