最近在做一個MS的項目,我負責一個檢索AD中的使用者和組資料資訊,這裡把她作為一個例子給大家分享。
首先從AD中查詢並構造一個對象池,查詢檢索AD資料是非常耗費時間的,為了不至於讓UI沒有響應,我採用了使用後台線程來運行AD檢索。下面是查詢AD中所有組使用的代碼:(順便說一下,DirectorySearcher和SearchResultCollection是System.DirectoryServices下的成員,在使用前要把System.DirectoryServices.dll添加引用項目中) 1 private static String[] GetAdGroupsFromAD()
2 {
3 DirectorySearcher srch = new DirectorySearcher();
4
5 const string query = "(&(objectCategory=group))";
6
7 srch.Filter = query;
8
9 SearchResultCollection sResult = srch.FindAll();
10
11 List<String> results = new List<string>();
12
13 if (null != sResult)
14 {
15 for (int i = 0; i < sResult.Count; i++)
16 {
17 if (null != sResult[i].Properties["name"] && sResult[i].Properties["name"].Count == 1)
18 {
19 results.Add(sResult[i].Properties["name"][0] as String);
20 }
21 }
22 }
23 return results.ToArray();
24 }
這個查詢在執行時是非常耗費時間的,由於查詢並不是非常頻繁的更改,所以我這裡使用一個緩衝池來儲存這些查詢結果。
由於緩衝池最後會被非同步訪問,可能會有多個線程同時訪問她,不得不使用其他來保證這個緩衝池狀態不被破壞。我採用建立一個鎖來確保同一時間只能有一個線程訪問。
private static Object m_groupPoolSync = new Object();
當向緩衝池讀寫資料的時候會對groupPoolSync 對象的加鎖。同時會有個全域標識來標識這個池是否已經初始化,這樣如果已經有了需要的資料就可以跳過對AD的檢索。 1private static String[] GetAdGroups()
2 {
3
4 List<String> results = new List<string>();
5
6 lock (m_groupPoolSync)
7 {
8 if (!m_groupPoolInitialized)
9 {
10 foreach (String result in GetAdGroupsFromAD())
11 {
12 m_groupPool.Add(result);
13 }
14
15 m_groupPoolInitialized = true;
16 }
17
18 results.AddRange(m_groupPool);
19 }
20
21 return results.ToArray();
22 }
有時必須把緩衝池清空,這裡使用一個統一的方法來做這個,這裡方法裡也對m_groupPoolSync進行了加鎖,因為有可能同時有另外一個線程調用GetAdGroups()方法。1 public static void ClearPools()
2 {
3 lock (m_groupPoolSync)
4 {
5 m_groupPoolInitialized = false;
6 }
7 }