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);
            }
        }
示例#3
0
        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());
        }
示例#4
0
        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);
        }
示例#10
0
        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();
            });
        }
示例#11
0
        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);
            }
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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");
            }
        }
示例#17
0
		/// <summary>
		/// 
		/// </summary>
		/// <param name="TimerAsync"></param>
		static public void ClearInterval(TimerAsync TimerAsync)
		{
			TimerAsync.Running = false;
		}
示例#18
0
		/*
		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;
		}
示例#19
0
		/// <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;
		}
示例#20
0
		/// <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;
		}