public void Play(IConsole console, bool cancelOnEscape = false) { bool isCancelled = false; Action playNotes = () => { foreach (var note in _notes) { var durationMilliseconds = _tempo.GetDurationMilliseconds(note.NoteDuration); if (note.NoteTone == Tone.Rest) { Thread.Sleep(durationMilliseconds); } else { console.Beep((int)note.NoteTone, durationMilliseconds); } if (isCancelled) { return; } } }; if (cancelOnEscape) { const char escape = (char)27; var playNotesTask = Task.Factory.StartNew( () => { playNotes(); if (!isCancelled) { console.SendChar(escape); } }); var readKeyTask = Task.Factory.StartNew( () => { while (console.ReadKey() != escape) { } isCancelled = true; }); Task.WaitAll(playNotesTask, readKeyTask); } else { playNotes(); } }