C# 无法使用与其基础RCW分离的COM对象-为什么会发生这种情况?
我有时会遇到以下例外情况: 无法使用已与其基础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
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用于解决你自己的问题,发布解决方案,更重要的是解决我来这里的问题。