I am trying to get a list of AD users with DirectorySearcher:
using (var entry = new DirectoryEntry("LDAP://mydomain.com"))
using (var search = new DirectorySearcher(entry))
{
search.PageSize = 1000;
using (SearchResultCollection results = search.FindAll())
{
foreach (SearchResult result in results)
{
}
}
}
This request can take up to a minute, so I start in a thread from a thread pool ( ThreadPool.QueueUserWorkItem). The query works fine and I get the correct results.
However, if I close the application at run-time of the request, I regularly get this the MDA: RaceOnRCWCleanup was detected. In fact, my thread is still running and waiting for the enumeration to continue:
[Managed to Native Transition]
System.DirectoryServices.dll!System.DirectoryServices.SearchResultCollection.ResultsEnumerator.MoveNext() + 0x4a bytes
MyApp.exe!MyApp.ActiveDirectory.FetchAllUsers() Line 125 + 0x4dd bytes
At the same time, the finalizer thread terminates the instance DirectoryEntry:
mscorlib.dll!System.__ComObject.ReleaseSelf() + 0x5 bytes
mscorlib.dll!System.Runtime.InteropServices.Marshal.ReleaseComObject(object o) + 0x84 bytes
System.DirectoryServices.dll!System.DirectoryServices.DirectoryEntry.Unbind() + 0x27 bytes
System.DirectoryServices.dll!System.DirectoryServices.DirectoryEntry.Dispose(bool disposing) + 0x29 bytes
System.dll!System.ComponentModel.Component.Finalize() + 0x1b bytes
I can verify (through Make Object IDin Visual Studio) that finalization DirectoryEntryis the internal instance used SearchResultCollection.
- Why
DirectoryEntrydoes this terminate when used yet? - , , , , , ?
- - ? .
1
GC.KeepAlive(results) foreach. GC.KeepAlive() DirectoryEntry results, . : ...
using (var entry = new DirectoryEntry("LDAP://mydomain.com"))
using (var search = new DirectorySearcher(entry))
{
using (SearchResultCollection results = search.FindAll())
{
var rootEntryField = typeof(SearchResultCollection).GetField("rootEntry", BindingFlags.NonPublic | BindingFlags.Instance);
var rootEntry = rootEntryField.GetValue(results);
foreach (SearchResult result in results)
{
}
GC.KeepAlive(results);
GC.KeepAlive(rootEntry);
}
GC.KeepAlive(search);
GC.KeepAlive(entry);
}
, , , SearchResultCollection , MDA. , , , , Dispose(). , GC , , ...
2
, , GC / , , , -, . , :
using (new MyFinalizableType())
{
System.Threading.Thread.Sleep(100000);
}
, , , , ~MyFinalizableType() , ( Threads).
, , GC , , RaceOnRCWCleanup MDA.
, GC.SuppressFinalize , COM , Dispose() . AFAIK COM , / .