You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET MAUI中WorkManager后台运行数小时后停止工作

.NET MAUI中WorkManager后台任务运行数小时后停止的问题

我在.NET MAUI中通过以下代码实现了WorkManager,将其配置为每30分钟执行一次后台任务。但成功运行约5-6小时后,任务不再按指定间隔触发,完全停止工作。请问代码是否存在问题?我是否遗漏了某些配置?

实现代码

using Android.App.Job;
using Android.Content;
using Android.Runtime;
using AndroidX.Work;

public class BackgroundWork : Worker
{
    public BackgroundWork(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }

    public BackgroundWork(Context context, WorkerParameters workerParams) : base(context, workerParams)
    {
    }

    public override Result DoWork()
    {
        //Analytics.TrackEvent("DoWork called.."+ DeviceInfo.Name);
        bool bResult = AlarmHelper.SetAlarms();

        if (bResult)
            return Result.InvokeSuccess();
        else
            return Result.InvokeFailure();
    }
    
    public override void OnStopped()
    {
        //Logger.LogEvent("BackgroundWork OnStopped");
        base.OnStopped();
    }
}

using AndroidX.Work;

public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        
#if __ANDROID__
        using var builder = new Constraints.Builder();
        builder.SetRequiredNetworkType(AndroidX.Work.NetworkType.Connected);
        var workConstraints = builder.Build();
        var interval = TimeSpan.FromMinutes(30);

        SetupWorker<BackgroundWork>(interval, workConstraints);
#endif
    }
    
    private void SetupWorker<TWorker>(TimeSpan interval, Constraints workConstraints) where TWorker : Worker
    {
        var request = PeriodicWorkRequest.Builder.From<TWorker>(interval)
            .SetConstraints(workConstraints)
            .Build();
        WorkManager.GetInstance(ApplicationContext)
            .EnqueueUniquePeriodicWork(nameof(TWorker), ExistingPeriodicWorkPolicy.Replace, request);        
    }
}

运行日志

Starting logging at 6/12/2023 6:44:25 PM
6/12/2023 6:44:28 PM : Bday Reminder Start.
6/12/2023 6:44:32 PM :      Done -- Reminders.0
6/12/2023 6:45:16 PM : Today Reminder Start.
6/12/2023 6:45:22 PM :   Done -- Reminders.0
6/12/2023 7:09:32 PM : PopulateDayChange -- called -> 6/12/2023 7:09:31 PM
6/13/2023 12:58:15 PM : PopulateDayChange -- called -> 6/13/2023 12:58:15 PM
6/13/2023 12:58:15 PM : Populate Day Change -- day change happened -> 6/13/2023 12:58:15 PM
6/13/2023 12:58:15 PM : Populate Day Change -- day change happened -> 6/13/2023 12:58:15 PM
6/13/2023 12:58:24 PM :          --- Done -- 6/13/2023 12:58:24 PM
6/13/2023 6:42:00 PM : PopulateDayChange -- called -> 6/13/2023 6:41:59 PM
6/13/2023 6:42:00 PM : PopulateDayChange -- called -> 6/13/2023 6:41:59 PM
6/13/2023 6:44:05 PM : PopulateDayChange -- called -> 6/13/2023 6:44:05 PM
6/13/2023 6:45:00 PM : Today Reminder Start.
6/13/2023 6:45:00 PM :   Done -- Reminders.2
6/13/2023 6:47:59 PM : PopulateDayChange -- called -> 6/13/2023 6:47:59 PM
6/13/2023 6:50:30 PM : PopulateDayChange -- called -> 6/13/2023 6:50:30 PM
6/14/2023 3:20:46 PM : PopulateDayChange -- called -> 6/14/2023 3:20:46 PM
6/14/2023 3:20:46 PM : Populate Day Change -- day change happened -> 6/14/2023 3:20:46 PM
6/14/2023 3:20:46 PM : Populate Day Change -- day change happened -> 6/14/2023 3:20:46 PM
6/14/2023 3:20:58 PM :          --- Done -- 6/14/2023 3:20:58 PM
6/14/2023 3:50:47 PM : PopulateDayChange -- called -> 6/14/2023 3:50:47 PM
6/14/2023 4:20:47 PM : PopulateDayChange -- called -> 6/14/2023 4:20:47 PM
6/14/2023 4:50:48 PM : PopulateDayChange -- called -> 6/14/2023 4:50:48 PM
6/14/2023 5:20:48 PM : PopulateDayChange -- called -> 6/14/2023 5:20:48 PM
6/14/2023 5:50:48 PM : PopulateDayChange -- called -> 6/14/2023 5:50:48 PM
6/14/2023 6:20:48 PM : PopulateDayChange -- called -> 6/14/2023 6:20:48 PM
6/14/2023 6:44:00 PM : Bday Reminder Start.
6/14/2023 6:44:01 PM :      Done -- Reminders.0
6/14/2023 6:45:00 PM : Today Reminder Start.
6/14/2023 6:45:01 PM :   Done -- Reminders.2
6/14/2023 6:50:49 PM : PopulateDayChange -- called -> 6/14/2023 6:50:49 PM
6/14/2023 7:20:49 PM : PopulateDayChange -- called -> 6/14/2023 7:20:49 PM
6/15/2023 11:08:06 AM : PopulateDayChange -- called -> 6/15/2023 11:08:06 AM
6/15/2023 11:08:06 AM : Populate Day Change -- day change happened -> 6/15/2023 11:08:06 AM
6/15/2023 11:08:08 AM :          --- Done -- 6/15/2023 11:08:08 AM
6/15/2023 11:38:08 AM : PopulateDayChange -- called -> 6/15/2023 11:38:08 AM
6/15/2023 12:08:08 PM : PopulateDayChange -- called -> 6/15/2023 12:08:08 PM
6/15/2023 12:47:09 PM : PopulateDayChange -- called -> 6/15/2023 12:47:09 PM
6/15/2023 1:17:09 PM : PopulateDayChange -- called -> 6/15/2023 1:17:09 PM

问题分析与解决方案

核心问题原因

  1. 系统电池优化节流:Android为延长续航,会对长时间运行的后台任务进行节流,即使使用WorkManager,数小时后也可能被降低执行频率或暂停,尤其是设备锁屏、低电量时。
  2. 网络约束限制:代码设置了NetworkType.Connected,若设备长时间无网络,任务会被挂起,直到网络恢复。
  3. 重试策略缺失:当DoWork返回失败时,WorkManager默认重试策略无法应对持续失败,可能导致任务停止调度。

针对性解决方案

  • 增加调度灵活性:给任务添加弹性间隔,让系统有更多调度空间,降低被节流概率:
    var request = PeriodicWorkRequest.Builder.From<BackgroundWork>(interval)
        .SetConstraints(workConstraints)
        .SetFlexInterval(TimeSpan.FromMinutes(10)) // 允许在周期最后10分钟内执行
        .Build();
    
  • 豁免电池优化:引导用户将应用加入电池优化白名单,避免系统完全暂停任务:
    var intent = new Intent(Android.Provider.Settings.ActionRequestIgnoreBatteryOptimizations, 
                            Android.Net.Uri.Parse("package:" + PackageName));
    StartActivity(intent);
    
  • 优化任务逻辑:确保DoWork操作轻量化,避免长时间运行(单个WorkManager任务最长允许10分钟执行时间),若AlarmHelper.SetAlarms()逻辑复杂,考虑拆分任务。
  • 添加状态监听:监听任务状态变化,记录停止原因以便排查:
    WorkManager.GetInstance(ApplicationContext)
        .GetWorkInfosForUniqueWorkLiveData(nameof(BackgroundWork))
        .Observe(this, workInfos => {
            foreach (var info in workInfos) {
                // 记录info.State(如Enqueued、Running、Failed、Cancelled等状态)
            }
        });
    
  • 配置重试策略:针对任务失败场景,添加指数退避重试配置:
    var request = PeriodicWorkRequest.Builder.From<BackgroundWork>(interval)
        .SetConstraints(workConstraints)
        .SetBackoffCriteria(BackoffPolicy.Exponential, TimeSpan.FromMinutes(5))
        .Build();
    

内容的提问来源于stack exchange,提问作者Sunil Parmar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 02:07:36