private void DynamicObjectAction(IDynamicObject obj) { // get the AutoResetEvent associated with the object id ares.TryGetValue(obj.Id, out AutoResetEvent are); // put the task to sleep until the main thread calls the Set() method. are.WaitOne(); //As long as the object is alive while (obj.State != State.Dead) { obj.Action(); //at the end of the action go to sleep obj.CalculateSleep(); // if the object is not sleeping // at the end of the day we inceremnt the number of finished tasks of the day. Interlocked.Increment(ref finishedTasksOfTheDay); // we call Set() with the AutoResetEvent variable associated with the main thread mainThreadARE.Set(); // we are withing for the main thread to call Set() at the next day. are.WaitOne(); } // after the object died we remove the key-value pair associated with it Interlocked.Increment(ref finishedTasksOfTheDay); mainThreadARE.Set(); ares.TryRemove(obj.Id, out _); }