/// <summary> /// Then main running part of main thread. /// <para></para> /// Main thread creates thread to run tasks, and manage the threads' count. /// </summary> private void Main() { while (toState != TaskPoolState.STOP) { run.WaitOne(); int count = 0; while (true) { locker.EnterReadLock(); count = running.Count; locker.ExitReadLock(); if (count >= maxThreadCount || toState != TaskPoolState.RUN) { break; } if (!AddThread()) { break; } } locker.EnterWriteLock(); if (count == 0) { currentState = TaskPoolState.PAUSE; } else { currentState = TaskPoolState.RUN; } locker.ExitWriteLock(); } }
/// <summary> /// Try to pause task box until no running tasks. /// </summary> /// <param name="waitInterval"></param> /// <returns></returns> public bool Pause(int waitInterval = 1000) { /// set toState to pause. locker.EnterWriteLock(); if (toState == TaskPoolState.RUN) { toState = TaskPoolState.PAUSE; } locker.ExitWriteLock(); TaskPoolState state; while (true) { locker.EnterReadLock(); state = currentState; locker.ExitReadLock(); if (state != TaskPoolState.RUN) { return(true); } Thread.Sleep(waitInterval); } }
/// <summary> /// Resume the task pool to fetch new tasks and run. /// </summary> public void Resume() { locker.EnterWriteLock(); toState = TaskPoolState.RUN; locker.ExitWriteLock(); run.Set(); }
private TaskBox(int maxThreadCount, bool isPreRunOne, bool isPostRunOne) { this.maxThreadCount = maxThreadCount; this.isPreRunOne = isPreRunOne; this.isPostRunOne = isPostRunOne; remains = new Queue <IPoolTask>(); running = new Dictionary <string, IPoolTask>(); toState = TaskPoolState.RUN; currentState = TaskPoolState.PAUSE; new Thread(Main).Start(); }
public static void Start() { if (_state == TaskPoolState.Unstarted) { _state = TaskPoolState.Starting; Init(); foreach (var queue in _pool) { new Thread(queue.Value.Dispatcher.Start).Start(); } _state = TaskPoolState.Running; } }
/// <summary> /// Constructor of TaskPool. /// </summary> /// <param name="taskGenerator"></param> /// <param name="maxThreadCount"></param> private TaskPool(IPoolTaskGenerator <IPoolTask> taskGenerator, int maxThreadCount) { toState = TaskPoolState.RUN; currentState = TaskPoolState.PAUSE; this.maxThreadCount = maxThreadCount; /// Start a thread to fetch <see cref="IPoolTask"/>. taskFetch = new TaskFetchThread(taskGenerator); Task thread = new Task(taskFetch.Run); thread.Start(); mainThread = new Thread(Main); mainThread.Start(); }
public static void Stop() { if (_state == TaskPoolState.Running) { _state = TaskPoolState.Stopping; foreach (var kvp in _pool) { kvp.Value.Dispatcher.Stop(); } while (_pool.Any(kvp => !kvp.Value.Dispatcher.IsIdle)) { Thread.Sleep(1000); } foreach (var kvp in _pool) { kvp.Value.Dispose(); } _pool.Clear(); _state = TaskPoolState.Unstarted; } }
/// <summary> /// Add a thread to run tasks. /// </summary> /// <returns></returns> private bool AddThread() { int count = 0; IPoolTask task = FetchTask(); if (task == null) { return(false); } Task thread = null; TaskPoolState m_toState; thread = new Task(() => { while (true) { if (task != null) { locker.EnterReadLock(); m_toState = toState; locker.ExitReadLock(); if (m_toState == TaskPoolState.RUN) { task.Run(); RemoveRunning(task); task = null; /// When finished a task, check <see cref="toState"/>. locker.EnterReadLock(); m_toState = toState; locker.ExitReadLock(); if (m_toState == TaskPoolState.RUN) { task = FetchTask(); if (task != null) { AddRunning(task, thread); } } } else { task.Cancel(); RemoveRunning(task, false); task = null; } } // When the intent is not to run, then cancel current task, if (task == null) { runningLocker.EnterReadLock(); count = running.Count; runningLocker.ExitReadLock(); if (count == 0) { locker.EnterWriteLock(); currentState = TaskPoolState.PAUSE; locker.ExitWriteLock(); } break; } } }); AddRunning(task, thread); thread.Start(); return(true); }
public void Stop() { Abort(); WakeUpAll(); State = TaskPoolState.Stopped; }
public void Start() { State = TaskPoolState.Started; foreach (var executor in _executors) { executor.Run(); } }
/// <summary> /// Create a thread, and fetch a task to run in it. /// </summary> /// <returns></returns> private bool AddThread() { if (toState != TaskPoolState.RUN) { return(false); } IPoolTask task = taskFetch.FetchNewTask(); if (task == null) { return(false); } Task thread = null; thread = new Task(() => { while (true) { task.Run(); /// When current task is finished, remove it from <see cref="running"/>. locker.EnterWriteLock(); running.Remove(task.Key); locker.ExitWriteLock(); /// If pool will run, then fetch a new task and add it to <see cref="running"/> if (toState == TaskPoolState.RUN) { task = taskFetch.FetchNewTask(); if (task != null) { locker.EnterWriteLock(); task.AttachThread(thread); running.Add(task.Key, task); locker.ExitWriteLock(); } } else { task = null; } /// When this thread are running to end, get count of running tasks. /// If count equals 0, it means there is no running task. /// Then set current state to <see cref="TaskPoolState.PAUSE"/> if (task == null) { int count = 0; locker.EnterUpgradeableReadLock(); count = running.Count; if (count == 0) { locker.EnterWriteLock(); currentState = TaskPoolState.PAUSE; locker.ExitWriteLock(); } locker.ExitUpgradeableReadLock(); break; } } }); task.AttachThread(thread); locker.EnterWriteLock(); running.Add(task.Key, task); locker.ExitWriteLock(); thread.Start(); return(true); }