public void TestLoopingRestart() { track.Looping = true; startPlaybackAt(track.Length - 1); Thread.Sleep(50); var resetEvent = new ManualResetEvent(false); Task.Run(() => { // The restart action is invoked during the update and will block if not invoked on the audio thread. // The update is always run on the audio thread in normal operation such that the restart action is always inlined. // The audio thread is faked here to simulate this operation and avoid a deadlock. Thread.CurrentThread.Name = GameThread.PrefixedThreadNameFor("Audio"); track.Update(); resetEvent.Set(); }); resetEvent.WaitOne(TimeSpan.FromSeconds(10)); track.Update(); Assert.IsTrue(track.IsRunning); Assert.LessOrEqual(track.CurrentTime, 1000); }
/// <summary> /// Certain actions are invoked on the audio thread. /// Here we simulate this process on a correctly named thread to avoid endless blocking. /// </summary> /// <param name="action">The action to perform.</param> private void runOnAudioThread(Action action) { var resetEvent = new ManualResetEvent(false); new Thread(() => { action(); resetEvent.Set(); }) { Name = GameThread.PrefixedThreadNameFor("Audio") }.Start(); if (!resetEvent.WaitOne(TimeSpan.FromSeconds(10))) { throw new TimeoutException(); } }
public static void RunOnAudioThread(Action action) { var resetEvent = new ManualResetEvent(false); new Thread(() => { ThreadSafety.IsAudioThread = true; action(); resetEvent.Set(); }) { Name = GameThread.PrefixedThreadNameFor("Audio") }.Start(); if (!resetEvent.WaitOne(TimeSpan.FromSeconds(10))) { throw new TimeoutException(); } }