public bool Start(uint frequencyInMsec, uint durationInMsec, ISampleSink sampleSink, INativeMethods nativeMethods)
        {
            _shutdownEvent.Reset();

            //atomic compare and set - if _workerRunning was a zero, it's now a 1 and create worker will be true
            bool createWorker = 0 == Interlocked.CompareExchange(ref _workerRunning, 1, 0);

            if (createWorker)
            {
                _samplingWorker = new Thread(() => InternalPolling_WaitCallback(frequencyInMsec, durationInMsec, sampleSink, nativeMethods))
                {
                    IsBackground = true
                };
                _samplingWorker.Start();
            }

            //return whether or not we created a session
            return(createWorker);
        }
        /// <summary>
        /// Polls for profiled threads.
        /// </summary>
        private void InternalPolling_WaitCallback(uint frequencyInMsec, uint durationInMsec, ISampleSink sampleSink, INativeMethods nativeMethods)
        {
            int samples = 0;

            var lastTickOfSamplingPeriod = DateTime.UtcNow.AddMilliseconds(durationInMsec).Ticks;

            try
            {
                while (!_shutdownEvent.Wait((int)frequencyInMsec))
                {
                    if (DateTime.UtcNow.Ticks > lastTickOfSamplingPeriod)
                    {
                        _shutdownEvent.Set();
                        Log.Debug("InternalPolling_WaitCallback: Duration Elapsed -- Stopping Sampler");
                        break;
                    }

                    try
                    {
                        var threadSnapshots = GetProfileWithRelease(out int result);
                        if (result >= 0)
                        {
                            ++samples;
                            sampleSink.SampleAcquired(threadSnapshots);
                        }
                        else
                        {
                            Log.Error($"Thread Profile sampling failed. ({result:X})");
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex);
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
            }
            finally
            {
                Log.Info($"samples ({samples})");

                sampleSink.SamplingComplete();

                nativeMethods.ShutdownNativeThreadProfiler();
                _workerRunning = 0;
            }
        }