private void ThreadStart(object number) { Culture.SetCurrentCulture(); int OurSleepTime = 0; int[] numbers = number as int[]; int ThreadNumber = numbers[0]; while (true) { try { Action item = null; if (!queue.TryDequeue(out item)) { OurSleepTime += m_info.SleepIncrementTime; if (m_info.KillThreadAfterQueueClear || OurSleepTime > m_info.MaxSleepTime) { Threads[ThreadNumber] = null; Interlocked.Decrement(ref nthreads); break; } else { Interlocked.Exchange(ref Sleeping[ThreadNumber], 1); Interlocked.Increment(ref nSleepingthreads); try { Thread.Sleep(OurSleepTime); } catch (ThreadInterruptedException) { } Interlocked.Decrement(ref nSleepingthreads); Interlocked.Exchange(ref Sleeping[ThreadNumber], 0); continue; } } else { // workers have no business on pool waiting times // that whould make interrelations very hard to debug // If a worker wants to delay its requeue, then he should for now sleep before // asking to be requeued. // in future we should add a trigger time delay as parameter to the queue request. // so to release the thread sooner, like .net and mono can now do. // This control loop whould then have to look for those delayed requests. // UBIT OurSleepTime = m_info.InitialSleepTime; item.Invoke(); } } catch { } Thread.Sleep(OurSleepTime); } }
/// <summary> /// Call the method and wait for it to complete or the max time. /// </summary> /// <param name="timeout"></param> /// <param name="enumerator"></param> /// <param name="isRunning"></param> /// <returns></returns> public static bool CallAndWait(int timeout, Heartbeat enumerator, out bool isRunning) { isRunning = false; bool RetVal = false; if (timeout == 0) { isRunning = enumerator(); RetVal = true; } else { //The action to fire FireEvent wrappedAction = delegate(Heartbeat en) { // Set this culture for the thread // to en-US to avoid number parsing issues Culture.SetCurrentCulture(); en(); RetVal = true; }; //Async the action (yeah, this is bad, but otherwise we can't abort afaik) IAsyncResult result = wrappedAction.BeginInvoke(enumerator, null, null); if (((timeout != 0) && !result.IsCompleted) && (!result.AsyncWaitHandle.WaitOne(timeout, false) || !result.IsCompleted)) { isRunning = false; return(false); } else { wrappedAction.EndInvoke(result); isRunning = true; } } //Return what we got return(RetVal); }
/// <summary> /// Run the loop through the heartbeats. /// </summary> protected internal void Run() { Culture.SetCurrentCulture(); try { List <InternalHeartbeat> hbToRemove = null; while ((m_timesToIterate >= 0) && (!startedshutdown)) { lock (m_lock) { foreach (InternalHeartbeat intHB in m_heartbeats) { bool isRunning = false; if (!CallAndWait(intHB.millisecondTimeOut, intHB.heartBeat, out isRunning)) { MainConsole.Instance.Warn( "[ThreadTracker]: Could not run Heartbeat in specified limits!"); } else if (!isRunning) { if (hbToRemove == null) { hbToRemove = new List <InternalHeartbeat>(); } hbToRemove.Add(intHB); } } if (hbToRemove != null) { foreach (InternalHeartbeat intHB in hbToRemove) { m_heartbeats.Remove(intHB); } //Renull it for later hbToRemove = null; if (m_heartbeats.Count == 0) //None left, break { break; } } } //0 is infinite if (m_timesToIterate != 0) { //Subtract, then see if it is 0, and if it is, it is time to stop m_timesToIterate--; if (m_timesToIterate == 0) { break; } } if (m_timesToIterate == -1) //Kill signal { break; } if (m_sleepTime != 0) { Thread.Sleep(m_sleepTime); } } } catch { } Thread.CurrentThread.Abort(); }