Created
March 9, 2015 19:29
-
-
Save blitzxion/64e4f60d56fbd9633364 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Written for LinqPad, sorry guys | |
| async void Main() | |
| { | |
| var pm = new PollerManager(); | |
| // var task1 = pm.Create(() => { @"LOOP 1".Dump(); }, () => { @"DONE 1".Dump(); }, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5)); | |
| // var task2 = pm.Create(() => { @"LOOP 2".Dump(); }, () => { @"DONE 2".Dump(); }, TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(10)); | |
| for (int i = 0; i < 10; i++) { | |
| pm.Create( | |
| string.Format(@"TASK_{0}", i), | |
| (x) => { string.Format(@"[{0}] LOOPED {1} TIMES", x.Name, x.NumTimesLooped).Dump(); }, | |
| (x) => { string.Format(@"[{0}] COMPLETED AFTER {1} LOOPS", x.Name, x.NumTimesLooped).Dump(); }, | |
| TimeSpan.FromSeconds(i + 1), | |
| TimeSpan.FromSeconds(i + 10) | |
| ); | |
| } | |
| // Run my tasks | |
| Task.Run(async() => { | |
| await pm.RunAll(); | |
| }); | |
| await Task.Delay(TimeSpan.FromSeconds(15)); | |
| // Cancel all my tasks | |
| pm.StopAll(); | |
| @"COMPLETE".Dump(); | |
| } | |
| // Define other methods and classes here | |
| public class PollerManager | |
| { | |
| readonly List<PollerTaskContainer> TaskList; | |
| public PollerManager() { | |
| TaskList = new List<PollerTaskContainer>(10); | |
| } | |
| public PollerTaskContainer Create (string name, Action<PollerTaskContainer> onPoll, Action<PollerTaskContainer> onEnd, TimeSpan interval, TimeSpan timeout) { | |
| var newTask = new PollerTaskContainer(name, onPoll, onEnd, interval, timeout); | |
| TaskList.Add(newTask); | |
| return newTask; | |
| } | |
| public PollerTaskContainer Create (PollerTaskContainer newTask) { | |
| TaskList.Add(newTask); | |
| return newTask; | |
| } | |
| public async Task RunAll() { | |
| if(TaskList != null) { | |
| var availableTasks = TaskList.Where (x => !x.IsRunning); | |
| string.Format(@"STARTING {0} TASK(S)", availableTasks.Count()).Dump(); | |
| await Task.WhenAll(availableTasks.Select (x => { return x.Run(); })); | |
| } | |
| } | |
| public void StopAll() { | |
| if(TaskList != null) { | |
| @"STOPPING ALL TASKS".Dump(); | |
| TaskList.ForEach(x => x.Stop()); // Stop them all... | |
| TaskList.Clear(); // Remove all tasks | |
| } | |
| } | |
| } | |
| public class PollerTaskContainer | |
| { | |
| public string Name { get; private set; } | |
| public int NumTimesLooped { get; private set; } | |
| CancellationTokenSource CTS { get; set; } | |
| TimeSpan PollInterval { get; set; } | |
| TimeSpan PollTimeout { get; set; } | |
| Action<PollerTaskContainer> OnEndAction { get; set; } | |
| Action<PollerTaskContainer> OnPollAction { get; set; } | |
| public bool IsRunning { get { return (CTS!=null) ? !CTS.IsCancellationRequested : false; } } | |
| /// Create a Task that acts on poll, with an action when it ends, on an interval, with a timeout | |
| public PollerTaskContainer(string name, Action<PollerTaskContainer> onPoll, Action<PollerTaskContainer> onEnd, TimeSpan interval, TimeSpan timeout) { | |
| Name = name; | |
| OnPollAction = onPoll; | |
| OnEndAction = onEnd; | |
| PollInterval = interval; | |
| PollTimeout = timeout; | |
| } | |
| public async Task Run() { | |
| if(CTS != null && !CTS.IsCancellationRequested) { | |
| CTS.Token.Register(()=>{ }); // Remove the onEndAction | |
| CTS.Cancel(); | |
| } | |
| NumTimesLooped = 0; | |
| CTS = new CancellationTokenSource(); | |
| CTS.Token.Register(() => { if(OnEndAction != null) OnEndAction(this); }); | |
| CTS.CancelAfter(PollTimeout); | |
| await PeriodicTask.Run(() => { NumTimesLooped++; if(OnPollAction != null) OnPollAction(this); }, PollInterval, CTS.Token); | |
| } | |
| public void Stop() { | |
| if(CTS != null && !CTS.IsCancellationRequested) { | |
| CTS.Cancel(); | |
| } | |
| } | |
| } | |
| public static class PeriodicTask { | |
| public static async Task Run(Action action, TimeSpan period, CancellationToken cancellationToken) { | |
| while(!cancellationToken.IsCancellationRequested) { | |
| try { | |
| await Task.Delay (period, cancellationToken); | |
| action (); | |
| } catch (TaskCanceledException) { | |
| // DO NOTHING. IT WAS CANCELLED... GEEZ MICROSOFT | |
| } | |
| } | |
| } | |
| public static Task Run(Action action, TimeSpan period) { | |
| return Run(action, period, CancellationToken.None); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment