设置一个超时期限。如果它无法加载,那么我们将放弃加载其余部分。
Github PR: https://github.com/SignalR/SignalR/commit/8adb268b458fec7abf0c9b53514e2a2cbac23799
private static bool PerformanceCounterExistsSlow(string categoryName, string counterName) { // Fire this off on an separate thread var task = Task.Factory.StartNew(() => PerformanceCounterExists(categoryName, counterName)); if (!task.Wait(_performanceCounterWaitTimeout)) { // If it timed out then throw throw new OperationCanceledException(); } return task.Result; } private static bool PerformanceCounterExists(string categoryName, string counterName) { return PerformanceCounterCategory.Exists(categoryName) && PerformanceCounterCategory.CounterExists(counterName, categoryName); }
但是SignalR的处理方案会存在一个问题,该线程仍然在挂起,导致应用程关闭后无法完全释放进程(未被释放的线程会导致该进程无法结束)。
//两秒超时限制 private readonly static TimeSpan _performanceCounterWaitTimeout = TimeSpan.FromSeconds(2); private void Test() { //设置线程取消信号 var ts = new System.Threading.CancellationTokenSource(); //标记取消Token System.Threading.CancellationToken ct = ts.Token; var task = new Task(() => PerformanceCounterCategory.Exists("Network Interface"),ct); try { //超时抛出,性能计数器一旦执行就有可能导致线程无限挂起 if (!task.Wait(_performanceCounterWaitTimeout)) throw new OperationCanceledException(); } catch (Exception ex) { logger.Error(ex.ToString()); //发送取消信号 ts.Cancel(); } }