private void CheckTimer(DateTime when) { if (_expireTimer.Status == TaskTimerStatus.Done || _expireTimer.When > when) { _expireTimer.Change(when, TaskEnv.New()); } }
public void New_TaskEnv_does_not_carry_state() { var state = new State(); TaskEnv.Current.SetState("foo", state); Assert.IsNull(TaskEnv.New().GetState <State>("foo")); }
private void InsertRecord(DirectoryRecord record) { // add value to directory lock (_directory) { _directory[record.Name] = record; } // check if value has an expiration time if (record.HasExpiration) { TimerFactory.New(record.Expiration, OnExpire, record.Name, TaskEnv.New()); } SaveToFileSystem(record.Name, record.Value); // notify event channel XDoc notify = new XDoc("insert").Attr("name", record.Name); if (record.HasExpiration) { notify.Attr("expire", record.Expiration); } notify.Add(record.Value); _events.Post(notify, new Result <DreamMessage>(TimeSpan.MaxValue)); }
public void TaskEnv_invoke_with_custom_dispatchqueue_sets_task_state() { var dispatchQueue = new TestDispatchQueue(); _log.Debug("setting up envs"); var currentState = new State(); State newState = null; TaskEnv.Current.SetState(currentState); var copiedEnv = TaskEnv.Clone(dispatchQueue); var newEnv = TaskEnv.New(dispatchQueue); var resetEvent = new AutoResetEvent(false); bool?hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow copiedEnv.Acquire(); copiedEnv.Acquire(); copiedEnv.Invoke(() => { _log.Debug("copied env invoke"); hasState = currentState == TaskEnv.Current.GetState <State>(); resetEvent.Set(); }); resetEvent.WaitOne(); dispatchQueue.LastItem.Wait(); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow newEnv.Acquire(); newEnv.Acquire(); newEnv.Acquire(); newEnv.Invoke(() => { _log.Debug("new env invoke"); hasState = currentState == TaskEnv.Current.GetState <State>(); newState = new State(); TaskEnv.Current.SetState(newState); resetEvent.Set(); }); resetEvent.WaitOne(); dispatchQueue.LastItem.Wait(); Assert.IsTrue(hasState.HasValue); Assert.IsFalse(hasState.Value); Assert.IsNotNull(newState); Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>()); Assert.AreNotEqual(currentState, newState); hasState = null; newEnv.Invoke(() => { _log.Debug("new env invoke 2"); hasState = newState == TaskEnv.Current.GetState <State>(); newEnv = TaskEnv.Current; resetEvent.Set(); }); resetEvent.WaitOne(); dispatchQueue.LastItem.Wait(); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); }
private static void FibonacciThreadPool(IDispatchQueue stp, int n, TimeSpan delay, out int value, out TimeSpan elapsed) { _log.Debug("FibonacciThreadPool"); var sw = Stopwatch.StartNew(); value = Fibonacci(stp, n, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp))).Wait(); sw.Stop(); elapsed = sw.Elapsed; }
public void TaskEnv_invoke_sets_task_state() { _log.Debug("setting up envs"); var currentState = new State(); State newState = null; TaskEnv.Current.SetState(currentState); var currentEnv = TaskEnv.Current; var newEnv = TaskEnv.New(); var resetEvent = new AutoResetEvent(false); bool?hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow currentEnv.Acquire(); currentEnv.Acquire(); currentEnv.Invoke(() => { _log.Debug("current env invoke"); hasState = currentState == TaskEnv.Current.GetState <State>(); resetEvent.Set(); }); resetEvent.WaitOne(); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow newEnv.Acquire(); newEnv.Acquire(); newEnv.Acquire(); newEnv.Invoke(() => { _log.Debug("new env invoke"); hasState = currentState == TaskEnv.Current.GetState <State>(); newState = new State(); TaskEnv.Current.SetState(newState); resetEvent.Set(); }); resetEvent.WaitOne(); Assert.IsTrue(hasState.HasValue); Assert.IsFalse(hasState.Value); Assert.IsNotNull(newState); Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>()); Assert.AreNotEqual(currentState, newState); hasState = null; newEnv.Invoke(() => { _log.Debug("new env invoke 2"); hasState = newState == TaskEnv.Current.GetState <State>(); newEnv = TaskEnv.Current; resetEvent.Set(); }); resetEvent.WaitOne(); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); }
private void OnExpire(TaskTimer timer) { var now = DateTime.UtcNow; List <Entry> expirations = null; lock (_expirationLookup) { // Note (arnec): Sort is cheap here since we're generally dealing with an already sorted or mostly sorted set at this point _orderedExpirations.Sort((a, b) => a.When.CompareTo(b.When)); while (_orderedExpirations.Count > 0) { var entry = _orderedExpirations[0]; if (entry.Removed) { // this item was already removed from the set, and no longer requires expiration, but does need removal from ordered set _orderedExpirations.RemoveAt(0); continue; } if (entry.When > now) { _expireTimer.Change(entry.When, TaskEnv.New()); break; } entry.Removed = true; _expirationLookup.Remove(entry.Key); _orderedExpirations.RemoveAt(0); _log.DebugFormat("expired item with key '{0}'", entry.Key); if (EntriesExpired == null) { continue; } if (expirations == null) { expirations = new List <Entry>(); } expirations.Add(entry); } } if (expirations == null) { return; } OnEntriesExpired(expirations); OnCollectionChange(); }
public void TaskEnv_invokenow_sets_task_state() { var currentState = new State(); State newState = null; TaskEnv.Current.SetState(currentState); var currentEnv = TaskEnv.Current; var newEnv = TaskEnv.New(); bool?hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow currentEnv.Acquire(); currentEnv.Acquire(); currentEnv.InvokeNow(() => { hasState = currentState == TaskEnv.Current.GetState <State>(); }); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); hasState = null; // Note: have to over acquire otherwise env is wiped after invokenow newEnv.Acquire(); newEnv.Acquire(); newEnv.Acquire(); newEnv.InvokeNow(() => { hasState = currentState == TaskEnv.Current.GetState <State>(); newState = new State(); TaskEnv.Current.SetState(newState); }); Assert.IsTrue(hasState.HasValue); Assert.IsFalse(hasState.Value); Assert.IsNotNull(newState); Assert.AreEqual(currentState, TaskEnv.Current.GetState <State>()); Assert.AreNotEqual(currentState, newState); hasState = null; newEnv.InvokeNow(() => { hasState = newState == TaskEnv.Current.GetState <State>(); newEnv = TaskEnv.Current; }); Assert.IsTrue(hasState.HasValue); Assert.IsTrue(hasState.Value); }
private static Result <int> Fibonacci(IDispatchQueue stp, int n, TimeSpan delay, Result <int> result) { if (!ReferenceEquals(result.Env.DispatchQueue, stp)) { _log.Error(string.Format("ERROR: wrong task env {0}, expected {1}.", result.Env.DispatchQueue, stp)); } stp.QueueWorkItem(delegate { Interlocked.Increment(ref _counter); switch (n) { case 0: if (delay > TimeSpan.Zero) { Thread.Sleep(delay); } result.Return(0); break; case 1: if (delay > TimeSpan.Zero) { Thread.Sleep(delay); } result.Return(1); break; default: Result <int> a = Fibonacci(stp, n - 1, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp))); Result <int> b = Fibonacci(stp, n - 2, delay, new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp))); new AResult[] { a, b }.Join(new Result(TimeSpan.MaxValue, TaskEnv.New(stp))).WhenDone(_ => { if (!ReferenceEquals(AsyncUtil.CurrentDispatchQueue, stp)) { _log.Error(string.Format("ERROR: wrong queue {0}, expected {1}.", AsyncUtil.CurrentDispatchQueue, stp)); } result.Return(a.Value + b.Value); }); break; } }); return(result); }
public void ElasticThreadPool_Multi_Staged_Fibonacci_Min_1_Max_30() { const int test = 4; // initialize data structures ElasticThreadPool[] stp = new ElasticThreadPool[test]; Result <int>[] results = new Result <int> [test]; for (int i = 0; i < test; ++i) { stp[i] = new ElasticThreadPool(1, 30); results[i] = new Result <int>(TimeSpan.MaxValue, TaskEnv.New(stp[i])); } // start test var sw = Stopwatch.StartNew(); for (int i = 0; i < results.Length; ++i) { _log.DebugFormat("--- FIBONACCI KICK-OFF: {0}", i); Fibonacci(stp[i], 30, TimeSpan.Zero, results[i]); Thread.Sleep(TimeSpan.FromSeconds(1)); } results.Join(new Result(TimeSpan.MaxValue)).Wait(); sw.Stop(); TimeSpan elapsed = sw.Elapsed; // check results for (int i = 0; i < test; ++i) { Assert.AreEqual(832040, results[i].Value, "result {0} did not match", i); } _log.Debug("Time: " + elapsed); _log.Debug("Work items processed: " + _counter); for (int i = 0; i < test; ++i) { stp[i].Dispose(); Assert.AreEqual(0, stp[i].WorkItemCount, "WorkQueue[{0}] items", i); Assert.AreEqual(0, stp[i].ThreadCount, "WorkQueue[{0}] threads", i); } }
//--- Class Methods --- /// <summary> /// Set an interval at which Garbage collection should be forced. /// </summary> /// <param name="t">Interval length.</param> public static void SetCollectionInterval(TimeSpan t) { _collectInterval = t; _collectTimer.Change(t, TaskEnv.New()); _log.DebugFormat("set collection interval to {0:0} seconds", t.TotalSeconds); }