我正在从 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);
快速说明,我只是在通过 WMI 调用(也使用MethodTimeout
)确认 PC 在线后才运行上述检查。通过我的早期测试,我知道在此之前检查目录最终效率低下。
我也愿意用更好的方法代替这种方法。