This project has moved and is read-only. For the latest updates, please go here.

good way to close media ?

Jun 29, 2015 at 12:52 PM
Edited Jun 29, 2015 at 12:56 PM
I have code in PlayerPage.xaml when i back old page to play new channel. I performing multiple times, it will exit the application! I have how to rectify this situation? _mediaStreamFacade.CloseAsync() ?
Thank you for reading.
if (null != player && player.Source != null)
                player.Source = null;
if (null == _mediaStreamFacade)
                return;
            _mediaStreamFacade.StopAsync(CancellationToken.None); // I can remove this ?
            var mediaStreamFacade = _mediaStreamFacade;

            _mediaStreamFacade = null;

            mediaStreamFacade.StateChange -= TsMediaManagerOnStateChange;
            // Don't block the cleanup in case someone is mashing the play button.
            // It could deadlock.
            mediaStreamFacade.DisposeBackground("MainPage CloseMedia");
Coordinator
Jul 2, 2015 at 5:51 AM
It shouldn't be hanging to the point where it needs such extra help...

It is possible that the StopAsync() call will throw an exception. Since the returned Task is ignored, it will get turned into an unhandled Task exception. Try capturing the task and feeding it to TaskCollector, like so:
   var stopTask = _mediaStreamFacade.StopAsync(CancellationToken.None);

   TaskCollector.Default.Add(stopTask, "Stop cleanup");
TaskCollector will turn a failed task into a Debug.WriteLine() in the debug build and will simply ignore the task failure in the Release build (so don't use it for stuff where a failure matters).

Come to think of it, a CloseAsync() would be better here. The convention in phonesm is that "Stop" is reversible (one should be able to call Play again), but "Close" is not expected to be undone.

Also, for what that code is trying to do, something like this would be safer (warning: I haven't even tried compiling it):
            var mediaStreamFacade = _mediaStreamFacade;

            _mediaStreamFacade = null;

            mediaStreamFacade.StateChange -= TsMediaManagerOnStateChange;

            var closeDisposeTask = CloseDisposeAsync(mediaStreamFacade, TimeSpan.FromSeconds(5));

            TaskCollector.Default.Add(closeDisposeTask, "MainPage closeDisposeTask");
with
    async Task CloseDisposeAsync(IMediaStreamFacade mediaStreamFacade, TimeSpan timeout)
    {
        try
        {
            var closeTask = mediaStreamFacade.CloseAsync();

            await Task.WhenAny(closeTask, Task.Delay(timeout)).ConfigureAwait(false);

            if (!closeTask.IsCompleted)
                TaskCollector.Default.Add(closeTask, "CloseDisposeAsync closeTask");

            mediaStreamFacade.DisposeBackground("MainPage CloseMedia");
        }
        catch (Exception ex)
        {
            Debug.WriteLine("...");
       }
   }
That gives the Close five seconds to try to stop things politely before throwing things over to Dispose, but does not block the caller.