private async void ProcessAsync()
        {
            if (Monitor.TryEnter(ProcessingSyncRoot, TimeSpan.FromMilliseconds(100)))
            {
                try
                {
                    while (Frames.TryDequeue(out var frame))
                    {
                        ProcessingFrames.Add(frame);
                    }

                    while (DetectedFaceEpochs.TryDequeue(out var epoch))
                    {
                        ProcessingDetectedFaceEpochs.Add(epoch);
                    }

                    if (!ProcessingFrames.Any() ||
                        !ProcessingDetectedFaceEpochs.Any())
                    {
                        return;
                    }

                    var expiredFaceDetectionEpochs = new List <TimeSpan>();
                    foreach (var epoch in ProcessingDetectedFaceEpochs)
                    {
                        if (MostRecentObservedSystemRelativeTime - epoch > FaceDetectionLatency)
                        {
                            expiredFaceDetectionEpochs.Add(epoch);
                            continue;
                        }

                        var framesByCorrelation = ProcessingFrames.GroupBy(frame => (frame.SystemRelativeTime.Value - epoch).Duration() < FrameCorrelationTimeSpan);
                        ProcessingFrames = framesByCorrelation.Where(g => g.Key == false).SelectMany(g => g).ToList();
                        var correlatedFrames = framesByCorrelation.Where(g => g.Key == true).SelectMany(g => g);

                        foreach (var correlatedFrame in correlatedFrames)
                        {
                            CollectionProgressed?.Invoke(this, new ExampleMediaFrameCollectionProgressedEventArgs(correlatedFrame));
                        }
                    }

                    foreach (var epoch in expiredFaceDetectionEpochs)
                    {
                        ProcessingDetectedFaceEpochs.Remove(epoch);
                    }
                }
                finally
                {
                    ProcessingFrames = ProcessingFrames.Where(frame => (frame.SystemRelativeTime.Value - MostRecentObservedSystemRelativeTime).Duration() < FaceDetectionLatency).ToList();
                    Monitor.Exit(ProcessingSyncRoot);
                }
            }
            await Task.Delay(TimeSpan.FromMilliseconds(100));
        }
        public void Dispose()
        {
            DelayedProcessingTrigger.Dispose();
            while (Frames.TryDequeue(out var frame))
            {
                frame.Dispose();
            }

            while (DetectedFaceEpochs.TryDequeue(out var epoch))
            {
            }
            while (FailureReasons.TryDequeue(out var epoch))
            {
            }

            ProcessingFrames.Clear();
            ProcessingDetectedFaceEpochs.Clear();
        }