已从其基础RCW分开COM对象不能使用 - 它为什么会发生?(COM object that has

2019-07-20 02:03发布

我有时会出现以下情况例外:不能使用已从与其基础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值发生。 有谁知道可能是什么原因?

我发现,当我处理的DirectoryEntry的ADUser便有与创造,我仍然在尝试使用ADUser便有对象这个错误发生。 然而,这是不是在上面贴的代码的情况。 是否有可能以某种方式的DirectoryEntry处置本身?

当我尝试许多Active Directory对象执行操作我也得到这个例外。 例如,当我尝试设置SecurityDescriptor一个几千个用户,我得到这个错误每次200-300用户。 当我建立新的连接后重试操作我不明白例外。 被检测到的消息raceonrcwcleanup。 我的应用程序不是多线程的。

任何帮助,将不胜感激。

Answer 1:

是的,这是可能的DirectoryEntry对象配置由于垃圾收集。 GC是在自己的线程运行,因此对RCW清理的比赛是可能的。

尝试引用保存在你的ADUser便有对象。 比如,它应该看起来像

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


Answer 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



文章来源: COM object that has been separated from its underlying RCW can not be used - why does it happen?