public void Dispose() { if (isDisposed) { return; } logger.Info(""); // Stop data streams DisableTransfer(); TerminateAsyncOperations(); WaitForAsyncOperationsCompletion(); logger.Info("Stopping playback"); try { player.Stop(); } catch (Exception e) { if (!(e is InvalidOperationException)) { logger.Error(e); } // Ignore. Will be raised if not playing :) } DetachEventHandlers(); DisposeStreams(); bufferController.Dispose(); DisposeAllSubjects(); DisposeAllSubscriptions(); // Shut down player logger.Info("Disposing ESPlayer"); // Don't call Close. Dispose does that. Otherwise exceptions will fly player.Dispose(); if (usesExternalWindow == false) { WindowUtils.DestroyElmSharpWindow(displayWindow); } logger.Info("Disposing Tokens"); // Clean up internal object activeTaskCts.Dispose(); clockGeneratorCts?.Dispose(); isDisposed = true; }