11using System ;
2+ using System . Collections ;
23using System . Collections . Generic ;
4+ using System . Linq ;
35using System . Threading ;
46
57namespace ezThread
68{
79 public class JobManager
810 {
911 private List < EZTHREAD > ezthreads = new List < EZTHREAD > ( ) ;
10- private List < Job > jobs = new List < Job > ( ) ;
11- public int threads ;
12- private CancellationTokenSource cts = new CancellationTokenSource ( ) ;
12+ private Queue < Job > qjob = new Queue < Job > ( ) ;
13+ private bool started = false ;
1314
1415 public JobManager ( List < Job > Jobs , int threadstouse )
1516 {
16- jobs = Jobs ;
17- threads = threadstouse ;
17+ qjob = new Queue < Job > ( Jobs ) ;
18+ for ( int i = 0 ; i < threadstouse ; i ++ )
19+ {
20+ addThread ( ) ;
21+ }
22+
23+ }
24+ public JobManager ( int threadstouse )
25+ {
26+ for ( int i = 0 ; i < threadstouse ; i ++ )
27+ {
28+ addThread ( ) ;
29+ }
1830 }
1931 //Requires the cancellation token source of the token you gave to your threads
20- public JobManager ( List < EZTHREAD > threads , CancellationTokenSource threadancellationTokenSource )
32+ public JobManager ( List < EZTHREAD > threads )
2133 {
2234 ezthreads = threads ;
23- cts = threadancellationTokenSource ;
2435 }
25- //Creates the threads and allocates jobs to them. Use this if you add or remove a job
26- public void build ( )
36+ public JobManager ( )
2737 {
28- ezthreads . Clear ( ) ;
29- int jobsperthread = jobs . Count / threads ;
30- int jindex = 0 ;
31- for ( int i = 0 ; i < threads ; i ++ )
32- {
33- List < Job > jobsT = new List < Job > ( ) ;
34- if ( i >= threads - 1 )
35- {
36- for ( int j = jindex ; j < jobs . Count ; j ++ )
37- {
38- jobsT . Add ( jobs [ j ] ) ;
39- }
40- }
41- else
42- {
43- for ( int j = 0 ; j < jobsperthread ; j ++ )
44- {
45- jobsT . Add ( jobs [ jindex ] ) ;
46- ++ jindex ;
47- }
48- }
49- addThread ( jobsT ) ;
50- }
5138 }
52- //Starts the threads, Make sure to build() before
39+
40+ //Starts the threads
5341 public void startThreads ( )
5442 {
55- foreach ( var thread in ezthreads )
43+ if ( ezthreads . Count <= 0 )
44+ {
45+ throw new Exception ( "Thread list empty" ) ;
46+ }
47+ else if ( qjob . Count <= 0 )
48+ {
49+ throw new Exception ( "Job list empty" ) ;
50+ }
51+ else
5652 {
57- thread . executeJobs ( ) ;
53+ foreach ( var thread in ezthreads )
54+ {
55+ thread . start ( ) ;
56+ }
57+
58+ started = true ;
5859 }
5960 }
6061 //Pauses all threads
61- public void pause ( )
62+ public void pauseThreads ( )
6263 {
6364 foreach ( var ezthread in ezthreads )
6465 {
6566 ezthread . pause ( ) ;
6667 }
68+ started = false ;
6769 }
6870 //Resumes all threads
69- public void resume ( )
71+ public void resumeThreads ( )
7072 {
7173 foreach ( var ezthread in ezthreads )
7274 {
7375 ezthread . resume ( ) ;
7476 }
77+ started = true ;
7578 }
7679 //Returns true if all threads are paused
7780 public bool isPaused ( )
@@ -89,18 +92,22 @@ public bool isPaused()
8992 //Kills all the threads
9093 public void killThreads ( )
9194 {
92- cts . Cancel ( ) ;
95+ foreach ( var ezthread in ezthreads )
96+ {
97+ ezthread . killThread ( ) ;
98+ }
99+ started = false ;
93100 }
94-
101+
95102 //Removes job to list
96103 public void removeJob ( Job j )
97104 {
98- jobs . Remove ( j ) ;
105+ qjob = new Queue < Job > ( qjob . Where ( s => s != j ) ) ;
99106 }
100107 //Adds job to list
101108 public void addJob ( Job j )
102109 {
103- jobs . Add ( j ) ;
110+ qjob . Enqueue ( j ) ;
104111 }
105112 //Kills specific thread (Thread IDs start at 0 and ends at threadAmount-1)
106113 public void killThread ( int id )
@@ -118,69 +125,166 @@ public bool isDone()
118125 }
119126 }
120127
128+ started = false ;
121129 return true ;
122130 }
123- //Adds thread to thread list
124- private void addThread ( List < Job > lj )
131+ //Adds thread to thread list and starts them if the manager is running
132+ public void addThread ( int Amount = 1 )
133+ {
134+ for ( int i = 0 ; i < Amount ; i ++ )
135+ {
136+ EZTHREAD ezt = new EZTHREAD ( qjob , ezthreads . Count ) ;
137+ ezthreads . Add ( ezt ) ;
138+ if ( started )
139+ {
140+ ezt . start ( ) ;
141+ }
142+ }
143+ }
144+ //Deletes specified amount of threads (Preferably use it when the manager isn't running)
145+ public void decreaseThreads ( int amount )
125146 {
126- EZTHREAD ezt = new EZTHREAD ( lj , cts . Token , ezthreads . Count ) ;
127- ezthreads . Add ( ezt ) ;
128- }
147+ if ( amount < ezthreads . Count )
148+ {
149+ for ( int i = 0 ; i < amount ; i ++ )
150+ {
151+ ezthreads . Last ( ) . killThread ( ) ;
152+ ezthreads . Remove ( ezthreads . Last ( ) ) ;
153+ }
154+ }
155+ else
156+ {
157+ foreach ( EZTHREAD ezt in ezthreads )
158+ {
159+ ezt . killThread ( ) ;
160+ }
161+ ezthreads . Clear ( ) ;
162+ started = false ;
163+ }
164+
165+ }
166+ //Deletes specified percentage of threads (Preferably use it when the manager isn't running)
167+ public void decreaseThreads ( double percentage )
168+ {
169+ int amount = Convert . ToInt32 ( ezthreads . Count * ( percentage / 100 ) ) ;
170+ if ( amount < ezthreads . Count )
171+ {
172+ for ( int i = 0 ; i < amount ; ++ i )
173+ {
174+ ezthreads . Last ( ) . killThread ( ) ;
175+ ezthreads . Remove ( ezthreads . Last ( ) ) ;
176+ }
177+ }
178+ else
179+ {
180+ foreach ( EZTHREAD ezt in ezthreads )
181+ {
182+ ezt . killThread ( ) ;
183+ }
184+ ezthreads . Clear ( ) ;
185+ started = false ;
186+ }
187+ }
188+ //Returns the amount of threads in the manager
189+ public int threadAmount ( )
190+ {
191+ return ezthreads . Count ;
192+ }
129193 }
130194
131195 public class EZTHREAD
132196 {
133197 public Thread t ;
134198 public readonly int ID ;
135- private CancellationToken ctx ;
136- private CancellationTokenSource cts = new CancellationTokenSource ( ) ;
137- private CancellationToken indvctx ;
138- private List < Job > jobs ;
139- public int killthreadafter = 0 ;
199+ private Queue < Job > jobs ;
140200 private bool paused = false ;
141- public EZTHREAD ( List < Job > lj , CancellationToken ct , int id )
201+ private bool killthread = false ;
202+ public EZTHREAD ( Queue < Job > lj , int id )
142203 {
143204 jobs = lj ;
144- ctx = ct ;
145205 ID = id ;
146206 ThreadStart ts = new ThreadStart ( ( ) =>
147207 {
148- foreach ( Job j in jobs )
208+ while ( true )
149209 {
150- for ( int i = 0 ; i < j . executions ; i ++ )
210+ if ( paused )
151211 {
152-
153- if ( paused )
212+ try
154213 {
155- try
156- {
157- Thread . Sleep ( Timeout . Infinite ) ;
158- }
159- catch
160- {
161- }
214+ Thread . Sleep ( Timeout . Infinite ) ;
162215 }
163- else if ( ctx . IsCancellationRequested || indvctx . IsCancellationRequested )
216+ catch
164217 {
165- break ;
166218 }
167-
168- j . execute ( ) ;
169219 }
220+ else if ( killthread )
221+ {
222+ break ;
223+ }
224+ else if ( jobs . Count != 0 )
225+ {
226+ var j = jobs . Dequeue ( ) ;
227+ if ( j != null )
228+ {
229+ j . execute ( ) ;
230+ }
231+ }
232+ else
233+ {
234+ break ;
235+ }
236+
170237 }
238+
171239 } ) ;
172-
173240 t = new Thread ( ts ) ;
174- indvctx = cts . Token ;
175241 }
176242
177- public void executeJobs ( )
243+ public void start ( )
178244 {
179- t . Start ( ) ;
180- if ( killthreadafter != 0 )
245+ killthread = false ;
246+ paused = false ;
247+ ThreadStart ts = new ThreadStart ( ( ) =>
181248 {
182- cts . CancelAfter ( killthreadafter ) ;
183- }
249+ Job j = new Job ( ( ) => { } ) ;
250+ while ( true )
251+ {
252+ if ( paused )
253+ {
254+ try
255+ {
256+ Thread . Sleep ( Timeout . Infinite ) ;
257+ }
258+ catch
259+ {
260+ }
261+ }
262+ else if ( killthread )
263+ {
264+ break ;
265+ }
266+ else if ( jobs . Count != 0 )
267+ {
268+ lock ( jobs )
269+ {
270+ j = jobs . Dequeue ( ) ;
271+ }
272+ if ( j != null )
273+ {
274+ j . execute ( ) ;
275+ }
276+ }
277+ else
278+ {
279+ break ;
280+ }
281+
282+ }
283+
284+ } ) ;
285+ t = new Thread ( ts ) ;
286+ t . Start ( ) ;
287+
184288 }
185289 public void pause ( )
186290 {
@@ -197,7 +301,7 @@ public bool isPaused()
197301 }
198302 public void killThread ( )
199303 {
200- cts . Cancel ( ) ;
304+ killthread = true ;
201305 }
202306 }
203307}
0 commit comments