已经从其底层RCW分离的COM对象不能使用 - 为什么会发生? [英] COM object that has been separated from its underlying RCW can not be used - why does it happen?

查看:772
本文介绍了已经从其底层RCW分离的COM对象不能使用 - 为什么会发生?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有时得到以下异常:
不能使用已从其底层RCW分离的COM对象



示例代码:

(AdUrganizationalUnit organizationalUnit = new AdOrganizationalUnit(ADHelper.GetDirectoryEntry(ouAdDn)))
$ {
}使用(AdUser user = organizationalUnit.AddUser(commonName))
{
//设置一些属性
user.Properties [key] .Add(value);

user.CommitChanges();

user.SetPassword(password); //使用Invoke设置

//必须在创建用户
后设置user.Properties [UserAccountControl]。

user.CommitChanges();

}
}

AdUser如下所示: p>

  public class AdUser:DirectoryEntry 
{
public AdUser(DirectoryEntry entry)
:base .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。我的应用程序不是多线程的。



任何帮助都会感激。

解决方案

p>似乎问题是由在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;保护集; }

public ActiveDirectoryObject(DirectoryEntry entry)
{
Entry = entry;
}

public void CommitChanges()
{
Entry.CommitChanges();
}

public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposal)
{
if(!this.disposed)
{
if b $ b {
if(Entry!= null)Entry.Dispose();
}
disposed = true;
}
}
}

public class AdUser:ActiveDirectoryObject
{
public AdUser(DirectoryEntry entry)
:base条目)
{
}
}

得到这些错误。
更多详细信息: http://directoryprogramming.net/forums/thread/7171。 aspx


I sometimes get the following exception: COM object that has been separated from its underlying RCW can not be used

Sample code:

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 looks like this:

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; 
} 
} 

This is simplified version of my code. The exception sometimes shows up, sometimes not. Most of the time it happens when I'm trying to set UserAccountControl value. Does anyone know what could be the reason?

I found out that this error happens when I dispose DirectoryEntry the AdUser was created with and I'm still trying to use AdUser object. However this is not the case in the code posted above. Is it possible that DirectoryEntry somehow disposes itself?

I also get this exception when I try to execute operation on many active directory objects. For example when I try to set SecurityDescriptor for one thousand users, I get this error every 200-300 users. When I retry operation after establishing new connections I don't get exception. The message is raceonrcwcleanup was detected. My app is not multithreaded.

Any help would be appreciated.

解决方案

It seems that the problem is caused by creating DirectoryEntry from NativeObject in AdUser. When I changed AdUser from:

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

And created wrapper that treats DirectoryEntry as a component:

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) 
{ 
} 
} 

Then I don't get these errors. Further details here: http://directoryprogramming.net/forums/thread/7171.aspx

这篇关于已经从其底层RCW分离的COM对象不能使用 - 为什么会发生?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆