2009-09-29 13 views
5

veces tengo la siguiente excepción: objeto COM que se ha separado de su RCW subyacente no puede ser utilizadoEl objeto COM que se ha separado de su RCW subyacente no se puede usar, ¿por qué ocurre?

Código de ejemplo:

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 se ve así:

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

Esta es una versión simplificada de mi código. La excepción a veces aparece, a veces no. La mayoría de las veces sucede cuando intento establecer el valor UserAccountControl. ¿Alguien sabe cuál podría ser el motivo?

descubrí que este error ocurre cuando dispongo DirectoryEntry la ADUser fue creado con y todavía estoy tratando de utilizar el objeto ADUser. Sin embargo, este no es el caso en el código publicado anteriormente. ¿Es posible que DirectoryEntry de alguna manera se deshaga?

También consigo esta excepción cuando intento ejecutar la operación en muchos objetos de Active Directory. Por ejemplo, cuando intento configurar SecurityDescriptor para mil usuarios, obtengo este error cada 200-300 usuarios. Cuando intento volver a operar después de establecer nuevas conexiones, no obtengo ninguna excepción. El mensaje es raceonrcwcleanup fue detectado. Mi aplicación no es multiproceso.

Cualquier ayuda sería apreciada.

Respuesta

2

Parece que el problema se debe a la creación de DirectoryEntry desde NativeObject en AdUser. Cuando cambié ADUser de:

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

y creó envoltorio que trata DirectoryEntry como un componente:

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

Entonces no entiendo estos errores. Más detalles aquí: http://directoryprogramming.net/forums/thread/7171.aspx

+0

** + 1 ** para resolver su propia pregunta, publicar la solución y, lo que es más importante, resolver exactamente el mismo problema por el que vine aquí. –

3

Sí, es posible que objeto DirectoryEntry está dispuesto debido a la recolección de basura. GC se ejecuta en su propio hilo, por lo que es posible competir en la limpieza de RCW.

tratar de salvar referencia a ella en su objeto ADUser. Es decir. debería verse como

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

Lo siento por no haber respuesta, traté de usar DirectoryEntry como componente y actualmente funciona bien. Más detalles: http://directoryprogramming.net/forums/thread/7171.aspx – empi

+0

Ok, estoy feliz de que un problema se resuelve –

+0

@empi: Debe copiar la respuesta del poste y que se refieren a añadir aquí como asnwer a tu propia pregunta Luego marque eso como la respuesta. Eso ayudaría a otros a buscar respuestas aquí. Es menos visible cuando solo publica un enlace en un comentario ... – awe

Cuestiones relacionadas