在UWP中调用后台任务时,RPC服务器不可用(Excep_FromHResult 0x800706BA)

时间:2016-03-16 04:08:12

标签: win-universal-app windows-10 windows-10-universal windows-10-mobile

我开发了UWP应用程序,它可以在后台或手机锁定时播放音频文件。该应用程序工作正常,一切似乎完美5-10分钟。之后,当我运行应用程序时,我无法播放音频文件,并且我在主题中附加了异常。但是,如果我重新启动应用程序,一切正常。我已经按照以下步骤添加了以下代码和项目来完成任务。

  1. 创建通用项目(Windows Universal)
  2. 添加了以下代码以发送背景信息

    BackgroundMediaPlayer.MessageReceivedFromBackground + = BackgroundMediaPlayer_MessageReceivedFromBackground;

  3. 添加了Windows组件运行时(Windows Universal),其代码如下

  4. 在Package.appxmanifest中添加了入口点和后台任务

    public sealed class AudioPlayer : IBackgroundTask {
        private BackgroundTaskDeferral deferral;
        private SystemMediaTransportControls systemmediatransportcontrol;
        public void Run(IBackgroundTaskInstance taskInstance) {
            systemmediatransportcontrol = BackgroundMediaPlayer.Current.SystemMediaTransportControls;
            systemmediatransportcontrol.ButtonPressed += systemmediatransportcontrol_ButtonPressed;
            systemmediatransportcontrol.PropertyChanged += systemmediatransportcontrol_PropertyChanged;
            systemmediatransportcontrol.IsEnabled = true;
            systemmediatransportcontrol.IsPauseEnabled = true;
            systemmediatransportcontrol.IsPlayEnabled = true;
            systemmediatransportcontrol.IsNextEnabled = true;
            systemmediatransportcontrol.IsPreviousEnabled = true;
    
            BackgroundMediaPlayer.Current.CurrentStateChanged += Current_CurrentStateChanged;
            BackgroundMediaPlayer.MessageReceivedFromForeground += BackgroundMediaPlayer_MessageReceivedFromForeground;
    
            deferral = taskInstance.GetDeferral();
    
            taskInstance.Canceled += TaskInstance_Canceled;
            taskInstance.Task.Completed += Taskcompleted;
        }
        void Taskcompleted(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args) {
            deferral.Complete();
        }
        private void TaskInstance_Canceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) {
            try {
                systemmediatransportcontrol.ButtonPressed -= systemmediatransportcontrol_ButtonPressed;
                systemmediatransportcontrol.PropertyChanged -= systemmediatransportcontrol_PropertyChanged;
    
                BackgroundMediaPlayer.Shutdown(); // shutdown media pipeline
            }
            catch (Exception) {
            }
            deferral.Complete();
        }
    
        void Current_CurrentStateChanged(MediaPlayer sender, object args) {
            MediaPlayer player = sender;
            switch (player.CurrentState) {
                case MediaPlayerState.Playing:
                    systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Playing;
                    break;
                case MediaPlayerState.Paused:
                    systemmediatransportcontrol.PlaybackStatus = MediaPlaybackStatus.Stopped;
                    break;
            }
        }
        void systemmediatransportcontrol_ButtonPressed(SystemMediaTransportControls sender, SystemMediaTransportControlsButtonPressedEventArgs args) {
            try {
                switch (args.Button) {
                    case SystemMediaTransportControlsButton.Play:
                        playTrack();
                        break;
                    case SystemMediaTransportControlsButton.Pause:
                        stopBeforePlaying();
                        break;
                    case SystemMediaTransportControlsButton.Next:
                        stopBeforePlaying();
                        nextTrack();
                        break;
                    case SystemMediaTransportControlsButton.Previous:
                        stopBeforePlaying();
                        previousTrack();
                        break;
                }
            }
            catch (Exception) {
                //Debug.WriteLine(ex.Message);
            }
        }
        void stopBeforePlaying() {
            MediaPlayer player = BackgroundMediaPlayer.Current;
            if (player != null)
                player.Pause();
        }
        void BackgroundMediaPlayer_MessageReceivedFromForeground(object sender, MediaPlayerDataReceivedEventArgs e) {
            object foregroundMessageType;
            if (e.Data.TryGetValue(ApplicationSettingsConstants.ChapterStatus, out foregroundMessageType)) {
                //do something here
            }
        }
        void UpdateUVCOnNewTrack() {
            //update buttons here
        }
        async void playTrack() {
            MediaPlayer player = BackgroundMediaPlayer.Current;
            try {
                if (...) {
                    //load track
                    player.Play();
                }
                else {
                    player.Pause();
                    MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
                }
            }
            catch (System.IO.DirectoryNotFoundException) {
                player.Pause();
                MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
            }
            catch (System.IO.FileNotFoundException) {
                player.Pause();
                MessageService.SendMessageToForeground(ApplicationSettingsConstants.ChapterStatus, (short)ChapterStatus.ForegroundFileNotFound);
            }
            finally {
                UpdateUVCOnNewTrack();
            }
        }
        void nextTrack() {
            //load next track
        }
        void previousTrack() {
            //load previous here
        }
    }
    
  5. 为什么我收到上述错误?

    注意:我已按照Microsoft Sample Background Audio for Windows Phone 8.1 Sample启用了背景音频播放器。

    谢谢!

1 个答案:

答案 0 :(得分:1)

某些情况可能会导致BackgroundAudio.Reference中的此异常Windows-universal-samples/Samples/BackgroundAudio/cs/BackgroundAudio/Scenario1.xaml.cs,函数ResetAfterLostBackground()的注释

  

后台任务确实存在,但它已经消失了。将前景恢复到初始状态。不幸的是,一旦后台任务丢失,任何在BackgroundMediaPlayer.Current上注销事物的尝试都将因RPC错误而失败。

添加此函数,并在捕获错误的地方调用它。

 const int RPC_S_SERVER_UNAVAILABLE = -2147023174; // 0x800706BA  
 private void ResetAfterLostBackground()
 {
     BackgroundMediaPlayer.Shutdown();
     try
     {
         BackgroundMediaPlayer.MessageReceivedFromBackground += BackgroundMediaPlayer_MessageReceivedFromBackground;
     }
     catch (Exception ex)
     {
         if (ex.HResult == RPC_S_SERVER_UNAVAILABLE)
         {
             throw new Exception("Failed to get a MediaPlayer instance.");
         }
         else
         {
             throw;
         }
     }
 }