/// <summary> Starts the worker if possible. </summary> /// <param name="work"> Inner work function to run. </param> public void Start(Action work) { if (isRunning) { throw new InvalidOperationException($"WorkPool.Worker.Start: {this} is already running! Stop worker before trying to restart it!"); } isRunning = true; isPaused = false; worked = 0; workedThisBreak = 0; // Wrap work function in another thread to loop thread = new Thread(() => { Thread self = thread; while (isRunning && (thread == self)) { //Thread.MemoryBarrier(); try { if (isPaused) { ThreadUtil.Hold(sleepTime); } else { work(); worked++; workedThisBreak++; } if (workPerBreak > 0 && workedThisBreak > workPerBreak) { workedThisBreak = 0; // Waiting... //Console.WriteLine($"{this} is waiting... running?{isRunning} paused?{isPaused}"); ThreadUtil.Hold(sleepTime); } } catch (Exception e) { errorHandler?.Invoke(e); } } }); thread.Name = $"{this}"; thread.Start(); }
/// <summary> Creates a new worker for the pool </summary> /// <returns> A new worker configured for this pool. </returns> private Worker MakePoolWorker() { Worker worker = new Worker(workPerBreak, sleepTime).OnError(errorHandler); worker.Start(() => { T item; if (workItemQueue.TryDequeue(out item)) { if (removedTemp.Contains(item)) { return; } try { workFn(item); //Console.WriteLine($"Worked on {item} in {worker} / {this} "); } catch (Exception e) { throw new Exception($"WorkPool.MakePoolWorker: Error in WorkPool {id}: ", e); } finally { if (removedTemp.Contains(item)) { removedTemp.Remove(item); } else { workItemQueue.Enqueue(item); } } } else { //Console.WriteLine($"No work to do, skipped in {this}"); try { ThreadUtil.Hold(sleepTime); } catch {} //catch (Exception e) { // throw new Exception($"WorkPool {id} thread interrupted!", e); //} } }); return(worker); }