/// <summary> /// This function serves as a callback method for queueing threads and /// when they complete. /// </summary> /// <param name="name">The name of the thread that is finished working.</param> void threadCallback(string name = "") { lock (m_Lock) { if (name != null) { if (m_ActiveThreads.ContainsKey(name)) { //decrement active threads and cleanup BaseWorker finishedThread = m_ActiveThreads[name]; m_ActiveThreads.Remove(name); m_DeadThreads.Add(finishedThread); } else { Console.WriteLine("Error: No Active threads with the name: " + name); } } else { Console.WriteLine("Error: Thread name is not valid."); } } }
protected void setActiveThreads() { while (m_Run) { DateTime start = DateTime.Now; if ((m_ActiveThreads.Count() < m_MaxThreads) && (m_ThreadQueue.Count > 0) ) { lock (m_Lock) { start = DateTime.Now; while (m_ActiveThreads.Count() < m_MaxThreads && m_ThreadQueue.Count() > 0 && DateTime.Now - start < TimeSpan.FromSeconds(2)) { //pop a thread and start, and increment active threads BaseWorker popThread = m_ThreadQueue[0]; m_ThreadQueue.RemoveAt(0); if (popThread != null && !m_ActiveThreads.ContainsKey(popThread.ThreadId.ToString())) { m_ActiveThreads[popThread.ThreadId.ToString()] = popThread; if (popThread.ThreadState == System.Threading.ThreadState.Unstarted) { popThread.Start(); } } } } } Thread.Sleep(120); } }
public void start() { BaseWorker th = new BaseWorker(runThreadsLoop); th.Name = "Main Thread Loop"; th.createThread(ref th); th.Start(); }
/// <summary> /// This function will create a thread for the worker. /// /// This is a child thread of a main worker thread. So /// it passes all the attributes of the parent thread to /// the child thread. /// </summary> /// <param name="worker">The worker thread to create a thread for.</param> /// <returns>The created thread.</returns> public void createThread(ref BaseWorker worker) { if (worker != this) { worker.queueCallback = queueCallback; worker.threadCallback = threadCallback; worker.progressCallback = progressCallback; worker.m_HistoryId = this.m_HistoryId; worker.m_UserId = this.m_UserId; worker.Params = this.Params; //worker.setProc(this.m_Proc); } if (progressCallback != null) { progressCallback(worker.m_HistoryId, ThreadManager.ThreadProcessState.ADDED); } Thread thread = null; if (worker.m_SimpleMethod != null) { thread = new Thread(worker.doWork); } else if (worker.m_ParamMethod != null) { ParameterizedThreadStart pts = new ParameterizedThreadStart(worker.doWorkP); thread = new Thread(pts); } if (thread != null) { thread.SetApartmentState(ApartmentState.STA); String name = m_ThreadIdName; if (String.IsNullOrEmpty(name)) { name = this.GetType().ToString(); } thread.Name = name + "-" + thread.ManagedThreadId; if (String.IsNullOrEmpty(worker.m_ThreadIdName)) { worker.m_ThreadIdName = thread.Name; } else { worker.m_ThreadIdName += "-" + thread.ManagedThreadId; } if (thread.Name.Length == 0) { Console.WriteLine("No name Thread."); } worker.setThread(thread); } }
/// <summary> /// This function serves as a callback method for queueing threads and /// when they complete. /// </summary> /// <param name="thread">A handle to the worker thread.</param> void queueCallback(BaseWorker thread) { lock (m_Lock) { //if worker isn't null then add thread to queue if (thread != null) { m_ThreadQueue.Add(thread); } } }
/// <summary> /// This function will take in a worker instance object, a callback handle, and /// a social media type. Then it will create and queue a thread for running. /// </summary> /// <param name="worker">The worker instance object.</param> public void createQueueThread(BaseWorker worker) { //create worker thread m_TotalThreads++; worker.queueCallback += new BaseWorker.queueCallbackDelegate(queueCallback); worker.threadCallback += new BaseWorker.threadCallbackDelegate(threadCallback); worker.progressCallback += new BaseWorker.progressCallbackDelegate(progressCallback); worker.m_SeedThread = true; worker.createThread(ref worker); lock (m_Lock) { //queue thread m_ThreadQueue.Add(worker); } }
// Pause all requested cancel threads protected void setCancelledThreads() { while (m_Run) { DateTime start = DateTime.Now; for (int i = 0; i < m_CancelThreads.Keys.Count && DateTime.Now - start < TimeSpan.FromSeconds(2); i++) { long uid = m_CancelThreads.Keys.ElementAt <long>(i); long hid = m_CancelThreads[uid]; for (int b = 0; b < m_ActiveThreads.Count && DateTime.Now - start < TimeSpan.FromSeconds(2); b++) { String key = m_ActiveThreads.Keys.ElementAt <String>(b); BaseWorker th = m_ActiveThreads[key]; if (false) { th.Stop(); } } for (int n = 0; n < m_ThreadQueue.Count && DateTime.Now - start < TimeSpan.FromSeconds(2); n++) { BaseWorker th = m_ThreadQueue[n]; if (false) { m_ThreadQueue.RemoveAt(n); n--; } } m_CancelThreads.Remove(uid); } Thread.Sleep(120); } }
/// <summary> /// This function serves as the master run thread loop. /// </summary> public void runThreadsLoop() { DateTime printStatusTime = DateTime.Now; int count = 0; BaseWorker cancelTh = new BaseWorker(this.setCancelledThreads); cancelTh.Name = "setCancelledThreads"; cancelTh.createThread(ref cancelTh); cancelTh.Start(); BaseWorker activeTh = new BaseWorker(this.setActiveThreads); activeTh.Name = "setActiveThreads"; activeTh.createThread(ref activeTh); activeTh.Start(); BaseWorker maxTh = new BaseWorker(this.setMaxThreads); maxTh.Name = "setMaxThreads"; maxTh.createThread(ref maxTh); maxTh.Start(); BaseWorker gcTh = new BaseWorker(this.gcCleanup); gcTh.Name = "gcCleanup"; gcTh.createThread(ref gcTh); gcTh.Start(); // maybe create 3 threads to manage the arrays. while (m_Run) { DateTime start = DateTime.Now; int completedThreads = 0; if (DateTime.Now - printStatusTime > TimeSpan.FromSeconds(5) && (m_DeadThreads.Count > 0 || m_ActiveThreads.Count > 0)) { start = DateTime.Now; for (int i = 0; i < m_DeadThreads.Count && DateTime.Now - start < TimeSpan.FromSeconds(2); i++) { if (m_DeadThreads[i] == null || m_DeadThreads[i].Join(150)) { //m_DeadThreads[i] = null; m_DeadThreads.RemoveAt(i); //Console.Write("."); i--; completedThreads++; } } #if DEBUG Console.WriteLine(m_InstanceName + "\n" + "Added Threads: " + m_TotalThreads + "\nQueued Threads: " + m_ThreadQueue.Count + "\nActive Threads: " + m_ActiveThreads.Count + "\nCompleted Threads: " + completedThreads + "\nDead Threads: " + m_DeadThreads.Count + "\nMax Threads: " + m_MaxThreads + "\nRequested Threads: " + MaxThreads); m_TotalThreads = 0; // added threads completedThreads = 0; #endif printStatusTime = DateTime.Now; } else { if (m_ActiveThreads.Count > m_MaxThreads) { Thread.Sleep(120); } //else // Thread.Sleep(300); } Thread.Sleep(120); } //update history to complete Console.WriteLine("All threads complete, press any key to continue."); }