/// <summary> /// Run the validation tests in a loop /// </summary> /// <param name="config">Config</param> /// <param name="token">CancellationToken</param> /// <returns>0 on success</returns> public int RunLoop(Config config, CancellationToken token) { this.config = config ?? throw new ArgumentNullException(nameof(config)); if (token == null) { throw new ArgumentNullException(nameof(token)); } DateTime dtMax = DateTime.MaxValue; // only run for duration (seconds) if (config.Duration > 0) { dtMax = DateTime.UtcNow.AddSeconds(config.Duration); } if (config.Sleep < 1) { config.Sleep = 1; } DisplayStartupMessage(config); List <TimerRequestState> states = new List <TimerRequestState>(); foreach (string svr in config.Server) { // create the shared state TimerRequestState state = new TimerRequestState { Server = svr, Client = OpenHttpClient(svr), MaxIndex = requestList.Count, Test = this, RequestList = requestList, // current hour CurrentLogTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0), Token = token, }; if (config.Random) { state.Random = new Random(DateTime.UtcNow.Millisecond); } states.Add(state); state.Run(config.Sleep, config.MaxConcurrent); } int frequency = int.MaxValue; int initialDelay = int.MaxValue; if (config.SummaryMinutes > 0) { foreach (TimerRequestState trs in states) { // get current summary int cMin = DateTime.UtcNow.Minute / config.SummaryMinutes * config.SummaryMinutes; trs.CurrentLogTime = trs.CurrentLogTime.AddMinutes(cMin); initialDelay = (int)trs.CurrentLogTime.AddMinutes(config.SummaryMinutes).Subtract(DateTime.UtcNow).TotalMilliseconds; frequency = config.SummaryMinutes * 60 * 1000; // start the summary log timer using Timer logTimer = new Timer(new TimerCallback(SummaryLogTask), trs, initialDelay, frequency); } } try { // run the wait loop if (dtMax == DateTime.MaxValue) { Task.Delay(-1, token).Wait(token); } else { // wait one hour to keep total milliseconds from overflowing while (dtMax.Subtract(DateTime.UtcNow).TotalHours > 1) { Task.Delay(60 * 60 * 1000, token).Wait(token); } int delay = (int)dtMax.Subtract(DateTime.UtcNow).TotalMilliseconds; if (delay > 0) { Task.Delay(delay, token).Wait(token); } } } catch (TaskCanceledException tce) { // log exception if (!tce.Task.IsCompleted) { Console.WriteLine($"Exception: {tce}"); return(1); } // task is completed return(0); } catch (OperationCanceledException oce) { // log exception if (!token.IsCancellationRequested) { Console.Write($"Exception: {oce}"); return(1); } // Operation was cancelled return(0); } catch (Exception ex) { Console.WriteLine($"Exception: {ex}"); return(-1); } // graceful exit return(0); }
/// <summary> /// Run the validation tests in a loop /// </summary> /// <param name="id">thread id</param> /// <param name="config">Config</param> /// <param name="token">CancellationToken</param> /// <returns></returns> public int RunLoop(Config config, CancellationToken token) { this.config = config ?? throw new ArgumentNullException(nameof(config)); if (token == null) { throw new ArgumentNullException(nameof(token)); } DateTime dtMax = DateTime.MaxValue; // only run for duration (seconds) if (config.Duration > 0) { dtMax = DateTime.UtcNow.AddSeconds(config.Duration); } // create the shared state TimerRequestState state = new TimerRequestState { MaxIndex = requestList.Count, Test = this, // current hour CurrentLogTime = new DateTime(DateTime.UtcNow.Year, DateTime.UtcNow.Month, DateTime.UtcNow.Day, DateTime.UtcNow.Hour, 0, 0), Token = token }; if (config.Random) { state.Random = new Random(DateTime.UtcNow.Millisecond); } if (config.Sleep < 1) { config.Sleep = 1; } DisplayStartupMessage(config); // start the timers using Timer timer = new Timer(new TimerCallback(SubmitRequestTask), state, 0, config.Sleep); using Timer logTimer = new Timer(new TimerCallback(SummaryLogTask), state, (int)state.CurrentLogTime.AddHours(1).Subtract(DateTime.UtcNow).TotalMilliseconds, 60 * 60 * 1000); try { // run the wait loop if (dtMax == DateTime.MaxValue) { Task.Delay(-1).Wait(token); } else { // wait one hour to keep total milliseconds from overflowing while (dtMax.Subtract(DateTime.UtcNow).TotalHours > 1) { Task.Delay(60 * 60 * 1000).Wait(token); } int delay = (int)dtMax.Subtract(DateTime.UtcNow).TotalMilliseconds; if (delay > 0) { Task.Delay(delay).Wait(token); } } } catch (OperationCanceledException ex) { // safe to ignore Console.WriteLine(ex.Message); } // graceful exit return(0); }