In my last post, I talked about handling the FileCompleted event from an AudioFileInputNode in a UWP application. Since this event is raised from a background thread, it’s important to get back onto the Dispatcher thread before making any updates to the overall AudioGraph, or changing the UI.

In UWP, this can be done by calling RunAsync on the Dispatcher. (By the way if you’re in a ViewModel then you can get at the Dispatcher with the rather cumbersome CoreApplication.MainView.CoreWindow.Dispatcher static property)

private async void FileInputNodeOnFileCompleted(AudioFileInputNode sender, object args)
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
        // code here runs on dispatcher thread

Now this works fine, but there is a nice alternative you can use if you’re working with Reactive Extensions. Rx makes it really easy for us to say that we want to observe an event on the Dispatcher thread. We do of course need to turn the event into an Observable first, which can be done with a call to Observable.FromEventPattern (which admittedly is a little bit cumbersome itself), but then we can say we want to observe it on the current SynchronizationContext (which is the Dispatcher thread in UWP).

Here’s a simple example:

Observable.FromEventPattern<EventHandler, EventArgs>(
h => audioEngine.FileCompleted += h,
h => audioEngine.FileCompleted -= h)
.Subscribe(f => OnPlaybackCompleted());

Now our event handler method OnPlaybackCompleted will run on the correct thread. Of course, on its own this may not seem a great improvement to using Dispatcher.RunAsync, but the benefit is that now it is an Observable, we can also make use of all the powerful composability that Rx brings.

Want to learn more about UWP application development and the powerful AudioGraph subsystem? Be sure to check out my Pluralsight course UWP Audio Fundamentals.
Vote on HN
comments powered by Disqus