public static Action StartUpAPollingLoop(Func <TimeSpan> drawTimeSpanDesired, DDoit doit) => StartUpAPollingLoopWithForceUpdateCapability(drawTimeSpanDesired, doit).KillTheLoop;
public static PollingLoopAccess StartUpAPollingLoopWithForceUpdateCapability(Func <TimeSpan> drawTimeSpanDesired, DDoit doit) { var l = NewLockWithControl(); bool wantOut = false; bool wantForceUpdate = false; new Thread( () => { DDoit current = doit; // only one thread will muck with this. while (true) { var timeStart = DateTime.Now; if ( With( l, c => wantOut)) { return; } var timeSpanDesired = drawTimeSpanDesired(); current = current(); for (; ;) { var timeEnd = DateTime.Now; var timeSpanSoFar = timeEnd - timeStart; if (wantForceUpdate) { wantForceUpdate = false; break; } else if (timeSpanSoFar < timeSpanDesired) { l(c => c.Wait(timeSpanDesired - timeSpanSoFar)); } else { break; } } } }).Start(); return (new PollingLoopAccess( killTheLoop: () => l( c => { wantOut = true; c.PulseAll(); }), forceLoopUpdateAsap: () => l( c => { wantForceUpdate = true; c.PulseAll(); }))); }