Active Directory から取得している PC のリストに対して並列操作を実行しています。この方法を使用して、コンピューターがオンラインかどうか、特定のディレクトリが存在するかどうかなど、PC の状態を確認していました。ただし、これらの操作の性質上、場合によっては時間がかかるため、タイムアウトを含めて、アプリケーションが引き続き操作できるようにしたいと考えました。
public static T MethodTimeout<T>(Func<T> f, int timeout, out bool completed)
{
T result = default(T);
var thread = new Thread(() => result = F());
thread.Start();
Completed = thread.Join(Timeout);
if (!Completed) thread.Abort();
return result;
}
これはほとんどの場合機能しますが、処理の使用量が少し急増したように見え、いくつかのケースではメモリ不足の例外に遭遇しました。ThreadPool
そのため、前述の問題が解消されることを期待して、タスクを使用する方法を変更しました。
public static T MethodTimeout<T>(Func<T> f, int timeout, out bool completed)
{
T result = default(T);
var timedTask = Task.Factory.StartNew(() => result = F());
Completed = timedTask.Wait(Timeout);
return result;
}
ThreadPool
ただし、これらの潜在的に長いタスクが完了するのを待ってハングしているプロセスでいっぱいになっているような気がします。タスクの関数をパラメーターとして渡しているため、キャンセル トークンを使用する方法がわかりません。ただし、これらのクラスでの私の経験は非常に限られているため、いくつかの優れたテクニックを見逃している可能性があります.
上記の方法を使用した方法は次のとおりです。
bool isReachable; // Check if the directory exists (1 second)
MethodTimeout(() => Directory.Exists(startDirectory), 1000, out isReachable);
簡単に言うと、上記のチェックは、PC が WMI 呼び出し (これも を使用MethodTimeout
) を介してオンラインであることを確認した後にのみ実行しています。初期のテストで、それが非効率になる前にディレクトリをチェックすることを認識しています。
また、このアプローチをより良いものに置き換えることにもオープンです。