ドメイン内のどのコンピュータが「非アクティブ」であるかを判断するメソッドを作成しようとしています。これを機能させることができた唯一の方法は、次を使用してコンピューターのIPアドレスを取得しようとすることです。
Dns.GetHostAddresses( computerName )
コンピューターが「非アクティブ」の場合、それをスローして、System.Net.Sockets.SocketException
そのコンピューターをキャッチして、非アクティブなコンピューターの DataTable に追加できます。この方法の問題点は、非常に遅いことです。私の Windows ドメインを 500 台のコンピューターで調べると、約 300 台が「非アクティブ」であり、この方法でそれらを並べ替えるのに約 30 分かかります。Windows ドメインに登録されているコンピューターがアクティブかどうかを確認する方法について、誰か提案はありますか?
また、リスト内のすべてのコンピューターに ping を実行してこれを実行しようとしましたが、「非アクティブ」なコンピューターに ping を実行しようとすると、 a がスローされ、System.Net.NetworkInformation.PingException
これをキャッチして同じ方法で処理する必要があります。これにより、このプロセスの実行時間も 30 分近くになります。
これが私のコードです。
public void findInactiveComputers( string customerName, string domain )
{
DirectoryEntry entry = new DirectoryEntry( domain );
DirectorySearcher searcher = new DirectorySearcher( entry );
searcher.Filter = ("(objectClass=computer)");
searcher.SizeLimit = int.MaxValue;
searcher.PageSize = int.MaxValue;
// Removes the inactive computers from the DataTable that associated with the customer.
if( _InactiveComputers.Rows.Count != 0 )
{
_InactiveComputers.AsEnumerable().Where( cust => cust["CustomerName"].ToString()
.Equals( customerName, StringComparison.InvariantCultureIgnoreCase ) )
.ToList().ForEach( comp => comp.Delete() );
}
foreach( SearchResult result in searcher.FindAll() )
{
if( result.GetDirectoryEntry().Name.StartsWith( "CN=" ) )
{
string computerName = result.GetDirectoryEntry().Name.Remove( 0, "CN=".Length );
try
{
Dns.GetHostAddresses( computerName );
}
catch( SocketException )
{
DataRow newRow = _InactiveComputers.NewRow();
newRow["ComputerName"] = computerName;
newRow["CustomerName"] = customerName;
_InactiveComputers.Rows.Add( newRow );
}
}
}
Properties.Settings.Default.InvalidComputers = _InactiveComputers;
Properties.Settings.Default.Save();
}
編集:
複数のスレッドを使用してタスクを実行しようとしましたが、待機時間が依然として非常に長いです (現在実行していますが、まだ完了していません)。
これが私がそれをどのように実装したかです。パフォーマンスを改善するための提案はありますか?
List<string> inactiveComputerNames = new List<string>();
foreach( SearchResult result in searcher.FindAll() )
{
new Thread( delegate()
{
if( result.GetDirectoryEntry().Name.StartsWith( "CN=" ) )
{
string computerName = result.GetDirectoryEntry().Name.Remove( 0, "CN=".Length );
try
{
Dns.GetHostAddresses( computerName );
}
catch( SocketException )
{
inactiveComputerNames.Add( computerName );
}
}
} ).Start();
}
foreach( string computerName in inactiveComputerNames )
{
DataRow newRow = _InactiveComputers.NewRow();
newRow["ComputerName"] = computerName;
newRow["CustomerName"] = customerName;
_InactiveComputers.Rows.Add( newRow );
}