コード例 #1
0
        void HandleNotification(ValueSet valueSet)
        {
            //Debug.WriteLine("BackgroundAudioRun.HandleNotification() " + _id);

            if (_completionSource.Task.IsCompleted)
            {
                return;
            }

            try
            {
                object idValue;

                if (valueSet.TryGetValue(BackgroundNotificationType.Id, out idValue))
                {
                    var id = idValue as Guid?;

                    if (id.HasValue && _appId.HasValue && id.Value != _appId.Value)
                    {
                        Debug.WriteLine("BackgroundAudioRun.HandleNotification() " + _id + " != " + id.Value);
                        return;
                    }
                }
                else
                {
                    Debug.WriteLine("BackgroundAudioRun.HandleNotification() no id " + _id);
                    return;
                }

                Guid?appId   = null;
                var  isStart = false;
                var  isStop  = false;

                foreach (var kv in valueSet)
                {
                    //Debug.WriteLine(" f->b {0}: {1}", kv.Key, kv.Value);

                    if (null == kv.Key)
                    {
                        Debug.WriteLine("*** BackgroundAudioRun.HandleNotification() null key");

                        continue; // This does happen.  It shouldn't, but it does.
                    }

                    BackgroundNotificationType type;
                    if (!Enum.TryParse(kv.Key, true, out type))
                    {
                        continue;
                    }

                    switch (type)
                    {
                    case BackgroundNotificationType.Start:
                    case BackgroundNotificationType.Resume:
                        isStart = true;
                        break;

                    case BackgroundNotificationType.Stop:
                    case BackgroundNotificationType.Suspend:
                        isStop = true;
                        break;

                    case BackgroundNotificationType.Ping:
                        if (_appId.HasValue)
                        {
                            _foregroundNotifier.Notify(BackgroundNotificationType.Pong, kv.Value);
                        }
                        break;

                    case BackgroundNotificationType.Pong:
                    {
                        var challenge = kv.Value as Guid?;

                        if (challenge.HasValue && challenge.Value == _challengeToken.Value)
                        {
                            _challengeCompletionSource.TrySetResult(challenge.Value);
                        }
                    }
                    break;

                    case BackgroundNotificationType.Smtc:
                        if (_appId.HasValue)
                        {
                            SystemMediaTransportControlsButton button;
                            if (Enum.TryParse((string)kv.Value, true, out button))
                            {
                                var mediaPlayerManager = _mediaPlayerManager;

                                if (null != mediaPlayerManager)
                                {
                                    HandleSmtcButton(mediaPlayerManager, button);
                                }
                            }
                        }
                        break;

                    case BackgroundNotificationType.Memory:
                        NotifyForegroundMemory();
                        break;

                    case BackgroundNotificationType.Gc:
                        var task = Task.Run(() =>
                        {
                            MemoryDiagnostics.DumpMemory();
                            Debug.WriteLine("Force GC: {0:F2}MiB", GC.GetTotalMemory(false).BytesToMiB());

                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            GC.Collect();

                            Debug.WriteLine("Forced GC: {0:F2}MiB", GC.GetTotalMemory(true).BytesToMiB());
                            MemoryDiagnostics.DumpMemory();

                            NotifyForegroundMemory();
                        });

                        TaskCollector.Default.Add(task, "Forced GC");

                        break;

                    case BackgroundNotificationType.Id:
                        var id = kv.Value as Guid?;

                        if (id.HasValue)
                        {
                            appId = id;
                        }

                        break;
                    }
                }

                if (!appId.HasValue)
                {
                    return;
                }

                if (_appId.HasValue)
                {
                    if (appId.Value != _appId.Value)
                    {
                        return;
                    }

                    if (isStop)
                    {
                        _appId = null;
                    }
                }
                else
                {
                    if (isStart)
                    {
                        _appId = appId.Value;
                    }
                    else
                    {
                        return;
                    }
                }

                if (isStop)
                {
                    StopWatchdog();
                }
                else if (!isStart)
                {
                    ResetWatchdog();
                }

                if (isStart)
                {
                    SyncNotification();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine("BackgroundAudioRun.HandleNotification() " + _id + " failed: " + ex.Message);
            }
        }
コード例 #2
0
        async Task RunAsync(IBackgroundTaskInstance taskInstance)
        {
            BackgroundTaskDeferral deferral = null;
            BackgroundAudioRun     run      = null;

            MemoryDiagnostics.DumpMemory();

            var usage = MemoryManager.AppMemoryUsage;
            var limit = MemoryManager.AppMemoryUsageLimit;

            if (usage + RequiredMemory > limit)
            {
                Debug.WriteLine("*** SmMediaBackgroundAudioTask.RunAsync() low memory");

                // We can't play anything because there isn't enough memory.  Force
                // the process to restart.

                try
                {
                    Application.Current.Exit();
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() exit failed " + ex.ExtendedMessage());
                }

                // Exit() didn't help, so we hog as much as we can of the remaining memory.

                MemoryHog.ConsumeAllMemory();

                BackgroundMediaPlayer.Shutdown();

                return;
            }

            var deferralId = Guid.NewGuid();

            try
            {
                Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() getting deferral " + deferralId);

                deferral = taskInstance.GetDeferral();

                try
                {
#if DEBUG
                    _memoryDiagnostics.StartPoll();
#endif

                    run = new BackgroundAudioRun(taskInstance.InstanceId);

                    var oldRun = Interlocked.Exchange(ref _run, run);

                    if (null != oldRun)
                    {
                        Debug.WriteLine("SmMediaBackgroundAudioTask.Run() run already exists");
                        oldRun.Dispose();
                    }

                    taskInstance.Canceled       += run.OnCanceled;
                    taskInstance.Task.Completed += run.OnTaskCompleted;

                    await run.ExecuteAsync().ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() failed " + ex.ExtendedMessage());
                }

                try
                {
#if DEBUG
                    _memoryDiagnostics.StopPoll();
#endif

                    var currentRun = Interlocked.CompareExchange(ref _run, null, run);

                    if (!ReferenceEquals(currentRun, run))
                    {
                        Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() mismatching run");
                    }

                    if (null != run)
                    {
                        taskInstance.Canceled       -= run.OnCanceled;
                        taskInstance.Task.Completed -= run.OnTaskCompleted;
                    }

                    if (null != run)
                    {
                        run.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() cleanup failed: " + ex.ExtendedMessage());
                }
            }
            finally
            {
                if (null != deferral)
                {
                    deferral.Complete();
                    Debug.WriteLine("SmMediaBackgroundAudioTask.RunAsync() released deferral " + deferralId);
                }
            }
        }