2009-09-29 328 views
5

私は時々、次の例外を取得:その基礎となるRCWから分離された COMオブジェクトが基になるRCWから分離されたCOMオブジェクトは使用できません - どうしてですか?

サンプル・コードを使用することはできません。

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

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は次のようになりますこれは私のコードの簡略化されたバージョンです。例外が時々現れることがあります。ほとんどの場合、UserAccountControl値を設定しようとしています。 誰かが理由を知ることができますか?

このエラーは、AdUserを作成したDirectoryEntryを処分してもAdUserオブジェクトを使用しようとしているときに発生することがわかりました。しかし、これは上記のコードでは当てはまりません。 DirectoryEntryが何とか自分自身を処理する可能性はありますか?

多くのアクティブなディレクトリオブジェクトに対して操作を実行しようとすると、この例外が発生します。たとえば、1000人のユーザーに対して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 **はあなた自身の質問を解決し、解決策を投稿し、さらに重要なことに私がここに来たのと全く同じ問題を解決します。 –

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

+0

問題が解決されたので、嬉しいです。 –

+0

@empi:あなたが参照する投稿から回答をコピーし、ここにasnwerとして追加する必要がありますあなた自身の質問。それを答えとしてマークします。それは他の人がここで答えを探すのに役立ちます。コメントにリンクを投稿すると表示されにくくなります。 – awe

関連する問題