UWP进程内AppService如何仅在宿主应用运行时接受连接?
更新内容
OnLaunched(LaunchActivatedEventArgs e)方法是否仅在用户手动启动应用的常规启动场景下触发?若如此,我打算通过布尔变量AppIsRunning跟踪应用运行状态,代码如下:
private static bool AppIsRunning = false; protected override async void OnLaunched(LaunchActivatedEventArgs e) { ... AppIsRunning = true; ... } private AppServiceConnection AppServiceConnection; private BackgroundTaskDeferral AppServiceDeferral; protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args) { base.OnBackgroundActivated(args); IBackgroundTaskInstance taskInstance = args.TaskInstance; AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails; AppServiceDeferral = taskInstance.GetDeferral(); taskInstance.Canceled += OnAppServicesCanceled; AppServiceConnection = appService.AppServiceConnection; AppServiceConnection.RequestReceived += OnAppServiceRequestReceived; AppServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed; } private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { if (AppIsRunning) { AppServiceDeferral messageDeferral = args.GetDeferral(); ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet(); await args.Request.SendResponseAsync(response); messageDeferral.Complete(); } } private void OnAppServicesCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason) { AppServiceDeferral.Complete(); } private void AppServiceConnection_ServiceClosed(AppServiceConnection sender, AppServiceClosedEventArgs args) { AppServiceDeferral.Complete(); }
请问该方案是否可行?
解答
核心结论
你的思路可行,但需要补充状态维护的逻辑,确保AppIsRunning能准确反映应用的活跃状态,同时可以优化连接拦截的时机。
细节补充与优化
OnLaunched的触发场景
OnLaunched并非只在用户手动启动时触发,应用从挂起状态恢复、通过协议激活等场景也会触发它,但如果应用是被AppService后台激活,OnLaunched不会执行——这刚好符合你的需求:此时AppIsRunning保持false,会自动拒绝连接。完善状态切换逻辑
当前代码只在OnLaunched中设置AppIsRunning = true,但没有处理应用进入后台/挂起的情况。当用户切换应用到后台,系统可能会挂起应用,此时需要把AppIsRunning设为false,避免出现应用已挂起但仍被标记为运行的错误:protected override void OnEnteredBackground(EnteredBackgroundEventArgs args) { base.OnEnteredBackground(args); AppIsRunning = false; } protected override void OnLeavingBackground(LeavingBackgroundEventArgs args) { base.OnLeavingBackground(args); AppIsRunning = true; }提前拦截非活跃状态的连接
你当前的代码是在请求进来时才判断是否处理,其实可以在OnBackgroundActivated阶段就直接拒绝连接,减少不必要的资源占用:protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args) { base.OnBackgroundActivated(args); IBackgroundTaskInstance taskInstance = args.TaskInstance; AppServiceTriggerDetails appService = taskInstance.TriggerDetails as AppServiceTriggerDetails; // 应用未运行时直接结束任务,不建立连接 if (!AppIsRunning) { var deferral = taskInstance.GetDeferral(); deferral.Complete(); return; } AppServiceDeferral = taskInstance.GetDeferral(); taskInstance.Canceled += OnAppServicesCanceled; AppServiceConnection = appService.AppServiceConnection; AppServiceConnection.RequestReceived += OnAppServiceRequestReceived; AppServiceConnection.ServiceClosed += AppServiceConnection_ServiceClosed; }请求处理的容错
即使在OnAppServiceRequestReceived中判断,也建议给客户端返回明确的拒绝响应,而不是静默忽略,这样客户端可以及时处理连接失败的情况:private async void OnAppServiceRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args) { var messageDeferral = args.GetDeferral(); if (AppIsRunning) { ValueSet response = (await IPC.Controller.ProcessIncomeRequests(args.Request.Message.ToDictionary())).ToValueSet(); await args.Request.SendResponseAsync(response); } else { // 返回明确的拒绝响应 await args.Request.SendResponseAsync(new ValueSet { { "Status", "Error" }, { "Message", "Host app is not running" } }); } messageDeferral.Complete(); }
内容的提问来源于stack exchange,提问作者Miguel
相关产品推荐
相关产品推荐

