internal static int Measure(string apiName, string hintStr, TimeSpan maxAllowedLatency, TimeSpan maxAllowedLatencyForTimer, TimerCallback latencyCallback, Func <int> func, out TimeSpan elapsed) { ExDateTime now = ExDateTime.Now; int num = 0; bool flag = true; Timer timer = null; Timer timer2 = null; try { if (latencyCallback != null && maxAllowedLatencyForTimer.TotalSeconds > 0.0) { LatencyChecker.LatencyContext latencyContext = new LatencyChecker.LatencyContext(now, apiName, hintStr, maxAllowedLatencyForTimer); timer = new Timer(latencyCallback, latencyContext, -1, -1); latencyContext.Timer = timer; timer.Change(maxAllowedLatencyForTimer, TimeSpan.FromMilliseconds(-1.0)); timer2 = new Timer(new TimerCallback(LatencyChecker.ReportClusApiHangLongLatency), latencyContext, -1, -1); TimeSpan dueTime = TimeSpan.FromSeconds((double)RegistryParameters.ClusApiHangReportLongLatencyDurationInSec); timer2.Change(dueTime, TimeSpan.FromMilliseconds(-1.0)); } if (RegistryParameters.IsApiLatencyTestEnabled) { LatencyChecker.DelayApiIfRequired(apiName); num = RegistryParameters.GetApiSimulatedErrorCode(apiName); if (num == 0) { num = func(); } else { NativeMethods.SetLastError(num); } } else { num = func(); } flag = false; } finally { if (flag) { num = -1; } if (timer != null) { timer.Change(-1, -1); timer.Dispose(); } if (timer2 != null) { timer2.Change(-1, -1); timer2.Dispose(); } elapsed = ExDateTime.Now - now; ExTraceGlobals.LatencyCheckerTracer.TraceDebug(0L, "Api={0}, StartTime={1}, Elapsed={2}, Hint={3}, IsUnhandled={4}, RetCode={5}, MaxLatency={6}", new object[] { apiName, now, elapsed, hintStr, flag, num, maxAllowedLatency }); if (elapsed > maxAllowedLatency || (num != 0 && RegistryParameters.GetIsLogApiLatencyFailure())) { ReplayCrimsonEvents.OperationTookVeryLongTimeToComplete.Log <string, ExDateTime, TimeSpan, string, bool, int, TimeSpan>(apiName, now, elapsed, hintStr, flag, num, maxAllowedLatency); } } return(num); }