2020年的UWP(4)——UWP和等待Request的Desktop Extension

上一篇咱們討論了UWP和Desktop Extension交互中,Desktop Extension執行後當即退出的場景。下圖是提到的四種場景分類:html

  • 執行後當即退出
  • 等待request,處理完後退出
  • 一或多個request/response週期
  • 和UWP程序相同生命週期

本篇咱們討論第二種,Desktop Extension等待request後,根據傳參完成操做後退出的,短生命週期場景。該類型有如下特徵:git

  1. 可能存在屢次的單向調用
  2. 經過request接收參數
  3. 不關心返回結果
  4. Desktop Extension等待request,完成操做後退出

該場景的示意圖以下:github

咱們依然以Desktop Extension啓動mspaint.exe和control.exe來舉例。和上一篇不一樣的是,此次咱們會經過UWP端發起的request來傳遞參數。安全

本篇Sample Code中的AppServiceHandler,以及App.xaml.cs中的OnBackgroundActivated方法。請參考《2020年的UWP(2)——In Process App Service》,相同部分再也不介紹。async

本篇新增的AppServiceConnectionConnectedEventArgs對象及Connected事件,是當AppServiceConnection經過OpenAsync方法成功鏈接時,傳遞當前活動的AppServiceConnection對象,以便調用SendMessageAsync等方法。this

    public class AppServiceConnectionConnectedEventArgs : EventArgs
    {
        public AppServiceConnection Connection { get; }

        public AppServiceConnectionConnectedEventArgs(AppServiceConnection connection)
        {
            Connection = connection;
        }
    }

   public event EventHandler<AppServiceConnectionConnectedEventArgs> Connected;

在AppServiceHandler中的OnBackgroundActivated方法中,咱們首要作的,便是通知訂閱對象,有AppServiceConnection被成功Open了,請及時響應。spa

        public void OnBackgroundActivated(AppServiceTriggerDetails details)
        {
            Connected?.Invoke(this, new AppServiceConnectionConnectedEventArgs(details.AppServiceConnection));
            Connection = details.AppServiceConnection;
            Connection.RequestReceived += Connection_RequestReceived;
        }

訂閱這個Connected事件的,通常都是Desktop Extension的發起方。好比說UWP端的某個Button。code

        private async void ButtonLaunchApp_Click(object sender, RoutedEventArgs e)
        {
            if (ApiInformation.IsApiContractPresent("Windows.ApplicationModel.FullTrustAppContract", 1, 0))
            {
                AppServiceHandler.Instance.Connected += Instance_Connected;
                await FullTrustProcessLauncher.LaunchFullTrustProcessForCurrentAppAsync();
            }
        }

        private async void Instance_Connected(object sender, AppServiceConnectionConnectedEventArgs e)
        {
            AppServiceHandler.Instance.Connected -= Instance_Connected;
            var valueSet = new ValueSet();
            valueSet.Add("FileName", ComboBoxFileName.SelectionBoxItem);
            var response = await e.Connection.SendMessageAsync(valueSet);
        }

之因此須要這個Connect事件,是由於經過SendMessageAsync傳參,須要依賴當前活動的AppServiceConnection對象。咱們正是經過Connected事件,將AppServiceConnection對象傳遞給訂閱者,使其可以訪問SendMessageAsync等方法進行數據交互。orm

在Instance_Connected方法中,在每次點擊按鈕時,均啓動一個新的Desktop Extension進程。在Desktop Extension進程中,會經過OpenAsync方法來鏈接AppServiceConnection。以後即是由OnBackgroundActivated方法觸發Connected事件,接下來就是發起request。htm

該場景中,Desktop Extension僅需維持一個較短的生命週期,在等到request後,根據傳參完成相應操做,就能夠釋放資源安全退出了。對整個APP而言,既不會長期佔用過多資源,也不會致使UWP端沒法Suspend。

下圖中的綠色葉子圖標,在Desktop Extension運行時,是不會出現的。

同時咱們要知道AppService的生命週期是不可控的,在UWP端程序最小化之後,Windows會在一段時間後中止AppService,AppServiceConnection也會被dispose。因此存儲一個AppServiceConnection長期對象,用來和永不退出的Desktop Extension通信並非個好主意。

如下是Desktop Extension端的部分代碼,爲了方便觀察應用程序的行爲,我在Sample中將Enrivonment.Exit給註釋掉了。

        public async Task InitializeAsync()
        {
            Connection = new AppServiceConnection();
            Connection.PackageFamilyName = Package.Current.Id.FamilyName;
            Connection.AppServiceName = "ParameterAppService";
            AppServiceConnectionStatus status = await Connection.OpenAsync();
            if (status != AppServiceConnectionStatus.Success)
            {
                Console.WriteLine(status);
            }
            else
            {
                Console.WriteLine(status);
                Connection.RequestReceived += Connection_RequestReceived;
            }
        }

        private void Connection_RequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            var content = args.Request.Message["FileName"].ToString();
            Process.Start(content);
            Console.WriteLine("Will exit after received.");
            //Environment.Exit(0);
        }

本篇簡單介紹了「等待request,處理完後退出」,這一UWP和Desktop Extension數據交互的場景。感謝看到這裏的同窗,單純的文字其實很難講清楚AppService的使用,還請參考Github上的實例代碼,歡迎評論及提問。

UWPSamples/UWPSamples/DataExchangeUWP/ExitAfterHandleRequest at master · manupstairs/UWPSamples (github.com)

相關文章
相關標籤/搜索