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

.NET Maui Android中Worker.DoWork如何维持事件驱动长时任务运行

问题与解决方案:AndroidX.Work.Worker维持长时加速度计监听

问题场景

在.NET Maui Android应用中,使用AndroidX.Work.Worker启动监听加速度计事件的长时进程,当前遇到的问题是:一旦DoWork方法退出,Worker就会终止,需要通过阻止DoWork退出来维持Worker运行。

解决方案代码

修改DropDetectorWorker类,通过ManualResetEventSlim阻塞DoWork方法,直到主动触发停止信号或Worker被系统终止:

using System.Threading;

public class DropDetectorWorker : AndroidX.Work.Worker
{
    private readonly ManualResetEventSlim _waitEvent = new ManualResetEventSlim(false);
    private readonly DropDetector _dropDetector = new DropDetector();
    private NotificationManager _notificationManager;
    private const string INITIAL_NOTIFICATION_CHANNEL_ID = "drop_detector_channel";
    private const string INITIAL_NOTIFICATION_CHANNEL_NAME = "Drop Detector";
    private static int NotificationId = 1001;

    public DropDetectorWorker(Context context, WorkerParameters workerParams) : base(context, workerParams)
    {
        _notificationManager = (NotificationManager)context.GetSystemService(Context.NotificationService);
    }

    public override Result DoWork()
    {
        CreateInitialNotificationChannel();
        
        var foregroundInfo = new ForegroundInfo(NotificationId++, BuildInitialNotification());
        SetForegroundAsync(foregroundInfo).Wait();
        
        InitialiseDropDetector();
        
        // 阻塞DoWork方法,直到_waitEvent被触发
        _waitEvent.Wait();
        
        // 清理资源
        _dropDetector.DropDetected -= DropDetector_DropDetected;
        _dropDetector.Stop();
        
        return Result.InvokeSuccess();
    }

    private void InitialiseDropDetector()
    {
        _dropDetector.DropDetected += DropDetector_DropDetected;
        _dropDetector.Start();
    }

    private void DropDetector_DropDetected(object sender, DropDetectedEventArgs e)
    {
        var lastDropDetected = DateTime.UtcNow;
        TriggerAutoclaimNotification(e.Magnitude);
        
        // 若需在某次检测后停止Worker,可在此调用:_waitEvent.Set();
    }

    private void CreateInitialNotificationChannel()
    {
        if (_notificationManager.GetNotificationChannel(INITIAL_NOTIFICATION_CHANNEL_ID) != null)
            return;
            
        NotificationChannel channel = new(INITIAL_NOTIFICATION_CHANNEL_ID, INITIAL_NOTIFICATION_CHANNEL_NAME, NotificationImportance.Default)
        {
            LightColor = Microsoft.Maui.Graphics.Color.FromRgba(0, 0, 255, 255).ToInt(),
            LockscreenVisibility = NotificationVisibility.Public
        };
    
        _notificationManager.CreateNotificationChannel(channel);
    }

    private Notification BuildInitialNotification()
    {
        return new Notification.Builder(Context, INITIAL_NOTIFICATION_CHANNEL_ID)
            .SetContentTitle("Drop Detector Running")
            .SetContentText("Listening for drop events")
            .SetSmallIcon(Resource.Drawable.ic_notification)
            .Build();
    }

    private Notification BuildMakeClaimNotification(double magnitude)
    {
        return new Notification.Builder(Context, INITIAL_NOTIFICATION_CHANNEL_ID)
            .SetContentTitle("Drop Detected!")
            .SetContentText($"Magnitude: {magnitude:F2}")
            .SetSmallIcon(Resource.Drawable.ic_notification_alert)
            .Build();
    }

    private void TriggerAutoclaimNotification(double magnitude)
    {
        var foregroundInfo = new ForegroundInfo(NotificationId++, BuildMakeClaimNotification(magnitude));
        SetForegroundAsync(foregroundInfo).Wait();
    }

    public override void OnStopped()
    {
        // 系统停止Worker时,触发信号解除阻塞
        _waitEvent.Set();
        base.OnStopped();
    }
}

关键说明

  • 用ManualResetEventSlim实现阻塞:DoWork末尾调用_waitEvent.Wait(),会一直阻塞直到_waitEvent.Set()被触发。
  • 处理系统终止场景:重写OnStopped方法,当系统主动停止Worker时,触发信号让DoWork退出并清理资源。
  • 资源清理:退出前移除事件订阅、停止检测器,避免内存泄漏。
  • 前台服务确保稳定:调用SetForegroundAsync时用.Wait(),保证前台服务设置完成后再启动监听。
  • 按需停止Worker:如果需要在某次掉落检测后终止任务,可在DropDetector_DropDetected事件中调用_waitEvent.Set()。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 20:40:21