已与其底层 RCW 分离的 COM 对象无法使用 - 为啥会发生这种情况?

Posted

技术标签:

【中文标题】已与其底层 RCW 分离的 COM 对象无法使用 - 为啥会发生这种情况?【英文标题】:COM object that has been separated from its underlying RCW can not be used - why does it happen?已与其底层 RCW 分离的 COM 对象无法使用 - 为什么会发生这种情况? 【发布时间】:2010-12-02 08:21:31 【问题描述】:

我有时会遇到以下异常: 已与其底层 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 是否有可能以某种方式自行处置?

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

任何帮助将不胜感激。

【问题讨论】:

【参考方案1】:

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

尝试在您的 AdUser 对象中保存对它的引用。 IE。它应该看起来像

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

【讨论】:

抱歉没有回应,我尝试使用 DirectoryEntry 作为组件,目前它工作正常。更多详情:directoryprogramming.net/forums/thread/7171.aspx @empi:您应该从您引用的帖子中复制答案并将其添加到此处作为您自己问题的答案。然后将其标记为答案。这将帮助其他人在这里寻找答案。当您只是在评论中发布链接时,它不太明显......【参考方案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

【讨论】:

+1 用于解决您自己的问题,发布解决方案,更重要的是解决我来这里的完全相同的问题。

以上是关于已与其底层 RCW 分离的 COM 对象无法使用 - 为啥会发生这种情况?的主要内容,如果未能解决你的问题,请参考以下文章

从 UWP 中的自定义 ToolTip 和自定义 Flyout 类取消订阅事件

VS2010不会显示项目属性(“底层RCW”)?

win10无法登录(调用的对象已与其客户端断开连接)

win10无法登录(调用的对象已与其客户端断开连接)

win10无法登录(调用的对象已与其客户端断开连接)

RCW 生存期控制