public Promise Start() { if (RenderImpl == null) { throw new InvalidOperationException($"You need to set the {nameof(RenderImpl)} property"); } stopRequested = false; last = DateTime.MinValue; var deferred = Deferred.Create(); Thread t = new Thread(() => { try { isRunning = true; stopRequested = false; Current = this; frameRateMeter = new FrameRateMeter(); Started.Fire(); while (!stopRequested) { lock (interactionQueue) { while (interactionQueue.Count > 0) { Add(interactionQueue.Dequeue()); } } while (DateTime.Now - last < _minTimeBetweenRenderIterations) { Thread.Sleep(0); } Tick(); RenderImpl(); AddedSinceLastRender.Clear(); RemovedSinceLastRender.Clear(); UpdatedSinceLastRender.Clear(); frameRateMeter.Increment(); } } catch (Exception ex) { if (ExceptionOccurred.HasSubscriptions) { ExceptionOccurred.Fire(ex); } deferred.Reject(ex); } finally { isRunning = false; try { Stopped.Fire(); if (deferred.IsFulfilled == false) { deferred.Resolve(); } } catch (Exception ex) { if (ExceptionOccurred.HasSubscriptions) { ExceptionOccurred.Fire(ex); } if (deferred.IsFulfilled == false) { deferred.Reject(ex); } } Current = null; } }); t.Priority = ThreadPriority.AboveNormal; t.IsBackground = true; t.Start(); return(deferred.Promise); }