2009-09-29 113 views
5

我有时会出现以下情况例外:不能使用具有与其基础RCW分开 COM对象已经与其基础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有可能以某种方式处置它自己吗?

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

任何帮助,将不胜感激。

回答

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

+0

** + 1 **为解决你自己的问题,发布解决方案,更重要的是解决我来到这里的完全相同的问题。 – 2014-04-20 17:17:25

3

是的,DirectoryEntry对象可能由于垃圾回收而丢弃。 GC运行在自己的线程中,因此可以在RCW清理上进行比赛。

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

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

对不起,我试图使用DirectoryEntry作为组件,目前它工作正常。更多详细信息:http://directoryprogramming.net/forums/thread/7171.aspx – empi 2009-10-10 23:02:18

+0

好的,我很高兴问题得到解决 – 2009-10-11 07:38:08

+0

@empi:您应该复制您引用的帖子中的答案,并将其添加为asnwer你自己的问题。然后将其标记为答案。这将有助于其他人在这里寻找答案。当你只是在评论中发布链接时,它不太明显... – awe 2009-12-08 09:40:21

相关问题