/// <summary>Runs the event loop for the current instance.</summary> /// <exception cref="InvalidOperationException">The current instance is already running.</exception> /// <exception cref="InvalidOperationException">The <see cref="ApartmentState" /> for the <see cref="Thread.CurrentThread" /> is not <see cref="ApartmentState.STA"/>.</exception> public void Run() { if (Interlocked.Exchange(ref _isRunning, 1) != 0) { ExceptionUtilities.ThrowInvalidOperationException(nameof(IsRunning), true); } var currentApartmentState = Thread.CurrentThread.GetApartmentState(); if (currentApartmentState != ApartmentState.STA) { ExceptionUtilities.ThrowInvalidOperationException(nameof(currentApartmentState), currentApartmentState); } var dispatchManager = DispatchManager; var currentDispatcher = dispatchManager.DispatcherForCurrentThread; var previousTimestamp = dispatchManager.CurrentTimestamp; while (_exitRequested == false) { currentDispatcher.DispatchPending(); var currentTimestamp = dispatchManager.CurrentTimestamp; var delta = currentTimestamp - previousTimestamp; var eventArgs = new IdleEventArgs(delta); OnIdle(eventArgs); previousTimestamp = currentTimestamp; } _exitRequested = false; _isRunning = 0; }
private void OnIdle(IdleEventArgs eventArgs) { Idle?.Invoke(this, eventArgs); }