public async Task Amount_Of_Time_Before_First_Execution_Of_Background_Workload_Equals_DueTime() { // ARRANGE var timeframes = new List <(DateTime start, DateTime end)>(); Func <CancellationToken, Task> action = async _ => { var startTime = DateTime.Now; await Task.Delay(500, CancellationToken.None).ConfigureAwait(false); var endTime = DateTime.Now; timeframes.Add((startTime, endTime)); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(300), TimeSpan.FromMilliseconds(500))) { // ACT var startingTime = DateTime.Now; target.Start(); await Task.Delay(350).ConfigureAwait(false); await target.Stop().ConfigureAwait(false); // ASSERT Assert.GreaterOrEqual(timeframes.Count, 1); var actualDueTime = timeframes[0].start - startingTime; Assert.GreaterOrEqual(actualDueTime, TimeSpan.FromMilliseconds(300)); } }
public async Task Amount_Of_Time_Between_Consecutives_Execution_Of_Background_Workload_Equals_Period() { // ARRANGE var timeframes = new List <(DateTime start, DateTime end)>(); Func <CancellationToken, Task> action = async _ => { var startTime = DateTime.Now; await Task.Delay(500, CancellationToken.None).ConfigureAwait(false); var endTime = DateTime.Now; timeframes.Add((startTime, endTime)); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(300), TimeSpan.FromMilliseconds(500))) { // ACT target.Start(); await Task.Delay(2100).ConfigureAwait(false); // in this amount of time background workload is executed at least 2 times await target.Stop().ConfigureAwait(false); // ASSERT Assert.GreaterOrEqual(timeframes.Count, 2); var timeframe1 = timeframes[0]; var timeframe2 = timeframes[1]; var actualPeriod = timeframe2.start - timeframe1.end; Assert.GreaterOrEqual(actualPeriod.TotalMilliseconds, 500); } }
public async Task OnError_Is_Raised_When_An_Error_Occurs_Inside_Background_Workload() { // ARRANGE int counter = 0; Func <CancellationToken, Task> action = _ => { counter++; if (counter >= 2) { throw new TestException("KABOOM !"); } return(Task.CompletedTask); }; var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); var mock = new Mock <ILogger>(); mock.Setup(m => m.Log(It.IsAny <string>())).Verifiable(); target.OnError += (object sender, Exception e) => mock.Object.Log($"An error occurred {e.Message}"); // ACT target.Start(); await Task.Delay(2500).ConfigureAwait(false); // ASSERT mock.Verify(m => m.Log(It.IsAny <string>()), Times.Once()); mock.Verify(m => m.Log("An error occurred KABOOM !"), Times.Once()); }
public async Task OnError_Is_Not_Called_When_Timer_Is_Stopped() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = _ => { values.Add(1); return(Task.CompletedTask); }; var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); var mock = new Mock <ILogger>(); mock.Setup(m => m.Log(It.IsAny <string>())).Verifiable(); target.OnError += (object sender, Exception e) => mock.Object.Log($"An error occurred {e.Message}"); // ACT target.Start(); await Task.Delay(2500).ConfigureAwait(false); await target.Stop().ConfigureAwait(false); await Task.Delay(2500).ConfigureAwait(false); // ASSERT mock.Verify(m => m.Log(It.IsAny <string>()), Times.Never()); }
public async Task Start_Schedules_Execution_Of_Background_Workload() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = _ => { values.Add(1); return(Task.CompletedTask); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500))) { // ACT target.Start(); await Task.Delay(1200).ConfigureAwait(false); // wait for the execution of background workload at least two times // ASSERT Assert.GreaterOrEqual(2, values.Count); Assert.IsTrue(values.All(value => value == 1)); } }
public async Task Start_Can_Be_Called_More_Than_Once_Without_Affecting_The_Execution_Of_Background_Workload() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = _ => { values.Add(1); return(Task.CompletedTask); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500))) { // ACT target.Start(); target.Start(); await Task.Delay(1200).ConfigureAwait(false); // ASSERT Assert.GreaterOrEqual(2, values.Count); Assert.IsTrue(values.All(value => value == 1)); } }
public async Task Stop_Terminates_Execution_Of_Scheduled_Background_Workload() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = ct => { ct.ThrowIfCancellationRequested(); values.Add(1); return(Task.CompletedTask); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500))) { // ACT target.Start(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice await target.Stop().ConfigureAwait(false); var snapshot1 = values.ToArray(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice (but now the timer is stopped) var snapshot2 = values.ToArray(); // ASSERT Assert.GreaterOrEqual(snapshot1.Length, 2); Assert.IsTrue(snapshot1.All(i => i == 1)); CollectionAssert.AreEqual(snapshot1, snapshot2); } }
public async Task Stop_Is_Thread_Safe() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = ct => { ct.ThrowIfCancellationRequested(); values.Add(1); return(Task.CompletedTask); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500))) { bool run = true; var thread1 = new Thread(() => { while (run) { target.Stop().Wait(); } }); var thread2 = new Thread(() => { while (run) { target.Stop().Wait(); } }); var threads = new[] { thread1, thread2 }; // ACT target.Start(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice threads.ForEach(t => t.Start()); await Task.Delay(2000).ConfigureAwait(false); run = false; threads.ForEach(t => t.Join()); var snapshot1 = values.ToArray(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice (but now the timer is stopped) var snapshot2 = values.ToArray(); // ASSERT Assert.GreaterOrEqual(snapshot1.Length, 2); Assert.IsTrue(snapshot1.All(i => i == 1)); CollectionAssert.AreEqual(snapshot1, snapshot2); } }
public void Start_Throws_ObjectDisposedException_When_Called_On_A_Disposed_Instance() { // ARRANGE var timer = new TimerAsync( _ => Task.CompletedTask, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); // ACT timer.Dispose(); Assert.Throws <ObjectDisposedException>(timer.Start); }
public void Start_Can_Be_Called_More_Than_Once_Without_Throwing_Exceptions() { // ARRANGE var target = new TimerAsync( _ => Task.CompletedTask, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); // ASSERT Assert.DoesNotThrow(() => { target.Start(); target.Start(); }); }
public void Stop_Can_Be_Called_Before_Start_Without_Throwing_Exceptions() { // ARRANGE var target = new TimerAsync( _ => Task.CompletedTask, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); // ASSERT Assert.DoesNotThrowAsync(async() => { await target.Stop().ConfigureAwait(false); target.Start(); await Task.Delay(1200).ConfigureAwait(false); }); }
public async Task Start_Is_Thread_Safe() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = _ => { values.Add(1); return(Task.CompletedTask); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500))) { bool run = true; var thread1 = new Thread(() => { while (run) { target.Start(); } }); var thread2 = new Thread(() => { while (run) { target.Start(); } }); var threads = new[] { thread1, thread2 }; // ACT threads.ForEach(t => t.Start()); await Task.Delay(1200).ConfigureAwait(false); run = false; threads.ForEach(t => t.Join()); // ASSERT Assert.GreaterOrEqual(2, values.Count); Assert.IsTrue(values.All(value => value == 1)); } }
public async Task It_Is_Possible_To_Execute_Background_Workload_Before_Previous_Execution_Completes() { // ARRANGE var iterationInfos = new ConcurrentBag <(DateTime start, DateTime end, int iterationNumber)>(); int counter = 0; Func <CancellationToken, Task> action = async _ => { var iterationNumber = Interlocked.Increment(ref counter); var startTime = DateTime.Now; await Task.Delay(300, CancellationToken.None).ConfigureAwait(false); var endTime = DateTime.Now; iterationInfos.Add((startTime, endTime, iterationNumber)); }; using (var target = new TimerAsync( action, TimeSpan.FromMilliseconds(40), TimeSpan.FromMilliseconds(40), canStartNextActionBeforePreviousIsCompleted: true)) { // ACT target.Start(); await Task.Delay(1000).ConfigureAwait(false); await target.Stop().ConfigureAwait(false); // ASSERT Assert.GreaterOrEqual(iterationInfos.Count, 2); // check the overlap var timeFrames = iterationInfos .OrderBy(tf => tf.iterationNumber) .Select(tf => (tf.start, tf.end)) .ToArray <(DateTime start, DateTime end)>(); var timeFrame1 = timeFrames[0]; var timeFrame2 = timeFrames[1]; Assert.IsTrue(timeFrame1.end > timeFrame2.start); } }
public async Task Start_Never_Executes_Background_Workload_When_DueTime_Equals_Infine_Timespan() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = _ => { values.Add(1); return(Task.CompletedTask); }; var target = new TimerAsync( action, Timeout.InfiniteTimeSpan, TimeSpan.FromMilliseconds(500)); // ACT target.Start(); await Task.Delay(2000).ConfigureAwait(false); // ASSERT CollectionAssert.IsEmpty(values); }
public async Task Stop_Can_Be_Called_More_Than_Once_Without_Changing_Expected_Behaviour() { // ARRANGE var values = new List <int>(); Func <CancellationToken, Task> action = ct => { ct.ThrowIfCancellationRequested(); values.Add(1); return(Task.CompletedTask); }; var target = new TimerAsync( action, TimeSpan.FromMilliseconds(500), TimeSpan.FromMilliseconds(500)); // ACT target.Start(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice await target.Stop().ConfigureAwait(false); await target.Stop().ConfigureAwait(false); var snapshot1 = values.ToArray(); await Task.Delay(1200).ConfigureAwait(false); // in 1200 milliseconds we are sure that action is called at least twice (but now the timer is stopped) await target.Stop().ConfigureAwait(false); var snapshot2 = values.ToArray(); // ASSERT Assert.GreaterOrEqual(snapshot1.Length, 2); Assert.IsTrue(snapshot1.All(i => i == 1)); CollectionAssert.AreEqual(snapshot1, snapshot2); }
private async void SendButton_Click(object sender, EventArgs e) { delayStart = TimeSpan.FromMilliseconds(1300); period = TimeSpan.FromMilliseconds(10); Func <CancellationToken, Task> func; string response; if (x13Button.Checked) { hexapod.udpHex.functionCode = 0x1301; } else { hexapod.udpHex.functionCode = 0x1401; } if (tabControl1.SelectedTab == tabPage1) { if (mvmtCB.Checked) { for (int i = 0; i < xes.Count; i++) { var x = xes[i].xPos; var t = xes[i].timer; response = await hexapod.asyncMove(x, x, x, x, x, x, t); } } else { if (useSineCB.Checked) { var x = sineVals2[0]; response = await hexapod.asyncMove(x, x, x, x, x, x, 1300); func = t => Doer2(); } else { var x = sineVals[0]; response = await hexapod.asyncMove(x, x, x, x, x, x, 1300); func = t => Doer(); } ctr++; tAsync = new TimerAsync(func, delayStart, period, false); tAsync.Start(); //for (int i = 0; i < 30; i++) //{ // var x = sineVals[i]; // if (i == 0) // { // response = await hexapod.asyncMove(x, x, x, x, x, x, 1000); // Thread.Sleep(2000); // } // else // { // response = await hexapod.asyncMove(x, x, x, x, x, x, 1000); // } //} } } else { response = await hexapod.ReadSetting("FN", 28, 1); ResponseBox.AppendText(response + "\r\n"); } }
/// <summary> /// /// </summary> /// <param name="TimerAsync"></param> static public void ClearInterval(TimerAsync TimerAsync) { TimerAsync.Running = false; }
/* static public TimerAsync SetTimeout(Action Action, TimeSpan TimeSpan) { return SetTimeout(() => new Task(Action), TimeSpan); } static public TimerAsync SetInterval(Action Action, TimeSpan TimeSpan) { return SetInterval(() => new Task(Action), TimeSpan); } */ /// <summary> /// /// </summary> /// <param name="TimerAsync"></param> static public void ClearTimeout(TimerAsync TimerAsync) { TimerAsync.Running = false; }
/// <summary> /// /// </summary> /// <param name="Action"></param> /// <param name="TimeSpan"></param> /// <returns></returns> static public TimerAsync SetInterval(Func<Task> Action, TimeSpan TimeSpan) { var TimerAsync = new TimerAsync(); Task.Run(async () => { while (TimerAsync.Running) { await Task.Delay(TimeSpan); if (TimerAsync.Running) await Action(); } }); return TimerAsync; }
/// <summary> /// /// </summary> /// <param name="Action"></param> /// <param name="TimeSpan"></param> /// <returns></returns> static public TimerAsync SetTimeout(Func<Task> Action, TimeSpan TimeSpan) { var TimerAsync = new TimerAsync(); Task.Run(async () => { await Task.Delay(TimeSpan); if (TimerAsync.Running) await Action(); }); return TimerAsync; }