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

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能准确反映应用的活跃状态,同时可以优化连接拦截的时机。

细节补充与优化

  1. OnLaunched的触发场景
    OnLaunched并非只在用户手动启动时触发,应用从挂起状态恢复、通过协议激活等场景也会触发它,但如果应用是被AppService后台激活,OnLaunched不会执行——这刚好符合你的需求:此时AppIsRunning保持false,会自动拒绝连接。

  2. 完善状态切换逻辑
    当前代码只在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;
    }
    
  3. 提前拦截非活跃状态的连接
    你当前的代码是在请求进来时才判断是否处理,其实可以在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;
    }
    
  4. 请求处理的容错
    即使在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:13:16