触发事件时在后台执行代码

时间:2017-04-25 16:43:13

标签: c# .net background event-handling uwp

我目前正在做事件中的所有工作,但这似乎不是首选方式,因为代码在几分钟不活动后不能在手机上执行。事件声明如下:

public PlaybackModel()
{
    ...
    queue.CurrentItemChanged += async (o, ea) =>
    {
        var res = ScrobbleHelper.TrySend(ea.OldItem);
        await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
        {
            var bg = App.Ref.IsBackground;
            currentItem = o.CurrentItem;
        });
    };
    ...
}

此事件似乎有5种可能的结果:

  1. 当应用程序位于前台时,scrobble正常工作;
  2. 当应用在后台工作且屏幕已开启(用户正在做其他事情)时,scrobble正常工作;
  3. 最近屏幕关闭时(当关闭屏幕后不久发送请求时)scrobble正常工作。
  4. 无法发送scrobble,因此当屏幕关闭超过一分钟时,它会被缓存(似乎互联网连接被切断,因此scrobble会在本地缓存);
  5. 如果屏幕长时间关闭,则根本不执行代码。
  6. 考虑到这一点,我正在考虑使用ApplicationTrigger的进程内后台任务调用scrobbler,但我不知道如何解决这个问题。

    一方面,这是唯一可以在没有应用程序在前台运行的情况下执行代码的东西,但另一方面,如果代码本身没有被事件处理程序调用,我不确定如果任务将被触发。

    UWP的任何其他API或功能是否有助于此情况?如果没有,我如何实施后台任务以达到最大效果?

    谢谢!

2 个答案:

答案 0 :(得分:0)

在Windows设备上,在前台应用程序中运行后台事件存在一些限制,即当屏幕关闭一段时间后它们会被冻结。它是为了减少电池消耗,整个过程在内存中暂停,没有事件发生。

有一种方法可以在专用进程上运行后台任务,即使设备未使用一段时间也能正常运行。您需要创建一个实现IBackgroundTask的专用类,然后将其固定到适当的触发器并进行注册。 (如果应用程序必须将内容写入应用程序状态,您还需要考虑一些IPC接口,因为后台任务作为不同的进程运行。)

答案 1 :(得分:0)

听起来您的应用正在播放媒体,并且您希望防止它在应用进入后台或屏幕被锁定时被暂停。最好的方法是使用去年发布的新的进程内背景媒体播放功能和周年纪念更新(1607)。这是文档:

https://docs.microsoft.com/en-us/windows/uwp/audio-video-camera/background-audio

需要注意的一点是,操作系统可能会在不使用时将网络适配器置于休眠状态。从你描述的症状来看,这可能是你在这里遇到的。尝试将此代码添加到您的应用中,以确保即使屏幕被锁定,网络连接仍然有效:

Windows.Media.Playback.MediaPlayer mp;
public void CreatePlayer()
{
  Windows.Media.Core.MediaBinder mb = new Windows.Media.Core.MediaBinder();
  mb.Binding += Mb_Binding;           
  var ms = Windows.Media.Core.MediaSource.CreateFromMediaBinder(mb);
  mp = new Windows.Media.Playback.MediaPlayer();
  mp.CommandManager.IsEnabled = false;
  mp.Source = ms;
}

private void Mb_Binding(Windows.Media.Core.MediaBinder sender, Windows.Media.Core.MediaBindingEventArgs args)
{
  var d = args.GetDeferral();
}

谢谢, Stefan Wick - Windows开发人员平台