/// <summary> /// Implementation using the ThreadPool with a wait event. /// </summary> private void DelayThreadPool() { lock (SyncRoot) { if (DelayEvent == null) { DelayEvent = WaitEventFactory.Create(isCompleted: true, useSlim: true); } } DelayEvent.Begin(); ThreadPool.QueueUserWorkItem(s => { DelaySleep(); DelayEvent.Complete(); }); DelayEvent.Wait(); }
static void Callback(IWaitEvent waitEvent) { try { waitEvent.Complete(); waitEvent.Begin(); } catch { // ignore } }
/// <summary> /// Runs the timer cycle. /// </summary> /// <param name="state">The state.</param> private void RunTimerCycle(object state) { // Handle the dispose process. if (IsDisposing) { if (ThreadingTimer != null) { ThreadingTimer.Dispose(); ThreadingTimer = null; } if (FormsTimer != null) { FormsTimer.Dispose(); FormsTimer = null; } if (DispatcherTimer != null) { DispatcherTimer.Stop(); DispatcherTimer = null; } DisposeCallback?.Invoke(); return; } // Skip running this cycle if we are already in the middle of one if (IsCycleDone.IsInProgress) { return; } // Start a cycle by signaling it IsCycleDone.Begin(); try { // Call the configured timer callback TimerCallback(); } catch { throw; } finally { // Finalize the cycle IsCycleDone.Complete(); } }
private void DelayThreadPool() { if (_delayEvent == null) { _delayEvent = WaitEventFactory.Create(isCompleted: true, useSlim: true); } _delayEvent.Begin(); ThreadPool.QueueUserWorkItem((s) => { DelaySleep(); _delayEvent.Complete(); }); _delayEvent.Wait(); }
/// <summary> /// Runs the timer cycle. /// </summary> /// <param name="state">The state.</param> private void RunTimerCycle(object state) { // Skip running this cycle if we are already in the middle of one if (IsCycleDone.IsInProgress) { return; } try { // Start a cycle by signaling it IsCycleDone.Begin(); // Call the configured timer callback TimerCallback(); } finally { if (HasRequestedStop == false) { // Finalize the cycle IsCycleDone.Complete(); } else { // Prevent a new cycle from being queued ThreadingTimer?.Change(Timeout.Infinite, Timeout.Infinite); FormsTimer?.Stop(); DispatcherTimer?.Stop(); // Handle the dispose process. ThreadingTimer?.Dispose(); FormsTimer?.Dispose(); // Remove references ThreadingTimer = null; FormsTimer = null; DispatcherTimer = null; // Complete the cycle and dispose of it IsCycleDone.Complete(); IsCycleDone.Dispose(); } } }
/// <summary> /// Begin playback /// </summary> public void Start() { if (DeviceHandle != IntPtr.Zero || IsDisposed) { throw new InvalidOperationException($"{nameof(AudioPlaybackThread)} was already started"); } PlaybackFinished.Begin(); var bufferSize = Renderer.WaveFormat.ConvertMillisToByteSize((DesiredLatency + NumberOfBuffers - 1) / NumberOfBuffers); // Acquire a device handle DeviceHandle = WaveInterop.OpenAudioDevice( DeviceNumber, Renderer.WaveFormat, DriverCallbackEvent.SafeWaitHandle.DangerousGetHandle(), IntPtr.Zero, WaveInterop.WaveInOutOpenFlags.CallbackEvent); // Create the buffers Buffers = new WaveOutBuffer[NumberOfBuffers]; for (var n = 0; n < NumberOfBuffers; n++) { Buffers[n] = new WaveOutBuffer(DeviceHandle, bufferSize, Renderer); } // Start the playback thread DriverCallbackEvent.Set(); // give the thread an initial kick AudioPlaybackThread = new Thread(PerformContinuousPlayback) { IsBackground = true, Name = nameof(AudioPlaybackThread), Priority = ThreadPriority.AboveNormal }; // Begin the thread AudioPlaybackThread.Start(); }