source: branches/eraser6/Manager/DirectExecutor.cs @ 152

Revision 152, 3.1 KB checked in by lowjoel, 6 years ago (diff)

-Implemented locks for the variables used across threads
-Implemented the polling loop used for processing the tasks

Line 
1using System;
2using System.Collections.Generic;
3using System.Collections.Specialized;
4using System.Text;
5using System.Threading;
6
7namespace Eraser.Manager
8{
9    /// <summary>
10    /// The DirectExecutor class is used by the Eraser GUI directly when the program
11    /// is run without the help of a Service.
12    /// </summary>
13    public class DirectExecutor : Executor
14    {
15        public DirectExecutor()
16        {
17            thread = new Thread(delegate()
18            {
19                this.Main();
20            });
21
22            thread.Start();
23            Thread.Sleep(0);
24        }
25
26        public override void AddTask(ref Task task)
27        {
28            lock (unusedIdsLock)
29            {
30                if (unusedIds.Count != 0)
31                {
32                    task.ID = unusedIds[0];
33                    unusedIds.RemoveAt(0);
34                }
35                else
36                    task.ID = ++nextId;
37            }
38
39            //Add the task to the set of tasks
40            lock (tasksLock)
41            {
42                tasks.Add(task.ID, task);
43
44                //If the task is scheduled to run now, break the waiting thread and
45                //run it immediately
46                if (task.Schedule == Schedule.RunNow)
47                {
48                    scheduledTasks.Add(DateTime.Now, task);
49                    schedulerInterrupt.Set();
50                }
51                //If the task is scheduled, add the next execution time to the list
52                //of schduled tasks.
53                else if (task.Schedule != Schedule.RunOnRestart)
54                {
55                    scheduledTasks.Add((task.Schedule as RecurringSchedule).NextRun, task);
56                }
57            }
58        }
59
60        public override bool DeleteTask(uint taskId)
61        {
62            lock (tasksLock)
63            {
64                if (!tasks.ContainsKey(taskId))
65                    return false;
66
67                lock (unusedIdsLock)
68                    unusedIds.Add(taskId);
69                tasks.Remove(taskId);
70            }
71            return true;
72        }
73
74        public override Task GetTask(uint taskId)
75        {
76            lock (tasksLock)
77            {
78                if (!tasks.ContainsKey(taskId))
79                    return null;
80                return tasks[taskId];
81            }
82        }
83
84        public override Dictionary<uint, Task>.Enumerator GetIterator()
85        {
86            return tasks.GetEnumerator();
87        }
88
89        private void Main()
90        {
91            //The waiting thread will utilize a polling loop to check for new
92            //scheduled tasks. This will be checked every 30 seconds. However,
93            //when the thread is waiting for a new task, it can be interrupted.
94            while (thread.ThreadState != ThreadState.AbortRequested)
95            {
96                //Check for a new task
97                Task task = null;
98                lock (tasksLock)
99                {
100                    if (scheduledTasks.Count != 0 &&
101                        (scheduledTasks.Values[0].Schedule == Schedule.RunNow ||
102                         scheduledTasks.Keys[0] <= DateTime.Now))
103                    {
104                        task = scheduledTasks.Values[0];
105                        scheduledTasks.RemoveAt(0);
106                    }
107                }
108
109                if (task != null)
110                {
111                    //Run the task
112                    ;
113                }
114
115                //Wait for half a minute to check for the next scheduled task.
116                schedulerInterrupt.WaitOne(30000, false);
117            }
118        }
119
120        private Thread thread;
121
122        private object tasksLock = new object();
123        private Dictionary<uint, Task> tasks = new Dictionary<uint, Task>();
124        private SortedList<DateTime, Task> scheduledTasks =
125            new SortedList<DateTime, Task>();
126
127        private List<uint> unusedIds = new List<uint>();
128        private object unusedIdsLock = new object();
129        private uint nextId = 0;
130
131        AutoResetEvent schedulerInterrupt = new AutoResetEvent(true);
132    }
133}
Note: See TracBrowser for help on using the repository browser.