UWP AppServiceConnection-SendResponseAsync返回AppServiceResponseStatus.Failure [英] UWP AppServiceConnection - SendResponseAsync returns AppServiceResponseStatus.Failure

查看:55
本文介绍了UWP AppServiceConnection-SendResponseAsync返回AppServiceResponseStatus.Failure的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Raspberry Pi3上创建一个UWP服务应用程序,以提供对板载UART的访问.我面临有关AppConnection请求/响应的问题.

I'm trying to create a UWP service app on the Raspberry Pi3 which provides the access to the on board UART. I'm facing an issue about the AppConnection Request/response.

这是处理来自客户端应用程序的传入请求的服务方法

this is the service method that handles the incoming requests from client apps

internal class Inbound
{
    public static async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
    {
        var messageDeferral = args.GetDeferral();
        var response = new ValueSet();

        bool success = false;
        var msg = args.Request.Message.Keys;
        if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.Command, out object command))
        {
            try
            {
                switch (command)
                {

                    case ServiceApiRequests.CommandValues.UartWrite:
                        if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.UartTxBuffer, out object txBuffer))
                        {
                            string rxBuff = "";
                            success = await Pi3.Peripherals.Uart.GerInstance(57600).Write((string)txBuffer);

                            if (success)
                            {
                                Debug.WriteLine("Tx: " + (string)txBuffer);
                                if (args.Request.Message.TryGetValue(ServiceApiRequests.Keys.ReadUartResponse, out object getResponse))
                                {
                                    if ((string)getResponse == ServiceApiRequests.ReadUartResponse.Yes)
                                    {
                                        rxBuff = await Pi3.Peripherals.Uart.GerInstance(57600).Read();
                                        Debug.WriteLine("Rx: " + rxBuff);
                                    }
                                }
                            }
                            response.Add(ServiceApiRequests.Keys.UartRxBuffer, rxBuff);

                        }
                        break;
                }
            }
            catch (Exception ex)
            {
                success = false;
            }
        }

        response.Add(new KeyValuePair<string, object>(ServiceApiRequests.Keys.Result, success ? ServiceApiRequests.ResultValues.Ok : ServiceApiRequests.ResultValues.Ko));
        var result = await args.Request.SendResponseAsync(response);
        if (result == AppServiceResponseStatus.Failure)
        {
            Debug.WriteLine("Failed to send the response");
        }
        messageDeferral.Complete();
    }
}

您可以发现,使用方法Pi3.Peripherals.Uart.GerInstance(57600)使用Singleton模式获取Uart类.

As you can figure out, the Uart class is get using the Singleton pattern using the method Pi3.Peripherals.Uart.GerInstance(57600).

遵循我用于从客户端应用发送请求的代码.

Following the code i using for send the request from the client app.

    public static class Uart
{
    public static IAsyncOperation<string> SendCommand(this AppServiceConnection DriverControllerConnection, string txBuffer, string awaitResponse = ServiceApiRequests.ReadUartResponse.Yes)
    {
        return _SendCommand(DriverControllerConnection, txBuffer, awaitResponse).AsAsyncOperation();
    }
    private static async Task<string> _SendCommand(AppServiceConnection DriverControllerConnection, string txBuffer, string awaitResponse)
    {
        AppServiceResponse response = null;
        string response_str = "";
        try
        {
            if (DriverControllerConnection != null)
            {
                response = await DriverControllerConnection.SendMessageAsync(new ServiceApiRequests.UartWrite().GetCommand(txBuffer, awaitResponse));
                if (response.Status == AppServiceResponseStatus.Success)
                {
                    if (response.Message.TryGetValue(ServiceApiRequests.Keys.Result, out object result))
                    {
                        if ((string)result == ServiceApiRequests.ResultValues.Ok && awaitResponse == ServiceApiRequests.ReadUartResponse.Yes)
                        {
                            response_str = response.Message[ServiceApiRequests.Keys.UartRxBuffer] as string;
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            // TODO: log
        }
        return response_str;
    }
}

该系统仅在一段时间内运行良好,直到出现response.Status == AppServiceResponseStatus.Success,然后请求的结果更改为AppServiceResponseStatus.Failure.这样,程序计数器就永远不会进入条件if (response.Status == AppServiceResponseStatus.Success).

The system works well just for a while, until i have response.Status == AppServiceResponseStatus.Success , then the result of the request changes and it becomes AppServiceResponseStatus.Failure. This way the program counter never steps into the condition if (response.Status == AppServiceResponseStatus.Success).

对原因有任何想法吗? 非常感谢您的帮助.

Any idea about the cause? Thank you so much for the help.

编辑

按照建议,我为ServiceClosed事件添加了一个处理程序.这是主要课程.

Follow the suggestions, i added an handler for the ServiceClosed event. This is the main class.

public sealed class DriverListener : IBackgroundTask
{
    private BackgroundTaskDeferral backgroundTaskDeferral;
    private AppServiceConnection appServiceConnection;
    public void Run(IBackgroundTaskInstance taskInstance)
    {
        backgroundTaskDeferral = taskInstance.GetDeferral();
        // taskInstance.Canceled += OnTaskCanceled;

        var triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
        appServiceConnection = triggerDetails.AppServiceConnection;
        appServiceConnection.RequestReceived += Inbound.OnRequestReceived;
        appServiceConnection.ServiceClosed += OnTaskCanceled;
    }

    private void OnTaskCanceled(AppServiceConnection sender, AppServiceClosedEventArgs reason)
    {
        if (this.backgroundTaskDeferral != null)
        {
            Debug.WriteLine("ServiceClosed");
            // Complete the service deferral.
            this.backgroundTaskDeferral.Complete();
        }
    }
}

在此函数中放置一个断点,我看到它从未被触发过. 使用单例模式打开应用程序连接,并将其放入我在客户端应用程序中使用的dll

Placing a breakpoint in this function, i see that it was never triggered. The app connection is opened using the singleton pattern, and putted in a dll that i use in the client app

    public static AppServiceConnection GetDriverConnectionInstance()
    {
        if (_DriverConnectionInstance == null)
        {
            try
            {
                _DriverConnectionInstance = OpenDriverConnection().AsTask().GetAwaiter().GetResult();
            }
            catch
            {

            }
        }
        return _DriverConnectionInstance;   
    }

我还向服务中添加了一个请求,该请求可以切换线索,并且我注意到线索状态发生了变化,但是来自应用程序服务的响应仍然是失败",并且消息为空.

I also add a Request to the service that toggles a led, and i noticed that the led status changes but the response from the app service is still "Failure" and the message is null.

推荐答案

除非前台经验要求,否则AppService的默认生存期为25秒.当服务关闭连接时,您的客户端进程将收到ServiceClosed事件,因此您知道下次您要发送请求时需要重新打开连接.

The AppService has a default lifetime of 25sec, unless it is being requested by the foreground experience. When the service shuts down the connection, your client process will receive the ServiceClosed event, so you know you will need to reopen the connection the next time you want to send a request.

这篇关于UWP AppServiceConnection-SendResponseAsync返回AppServiceResponseStatus.Failure的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆