Skip to content

Writing a mapping from a synchronous member to an asynchronous member

Luis Diego Fallas edited this page Sep 8, 2015 · 5 revisions

Many APIs in the new UWP platform use the Async/Await C#/VB feature that makes it easy to write non blocking operations.

For example the System.Windows.MessageBox.Show functionality is now available as an async operation exposed by the Windows.UI.Popups.MessageDialog.ShowAsync method.

-- Windows Phone Silverlight --

partial class MyPage ...
{
    ...
    private void OnClick(object sender, RoutedEventArgs e)
    {
       var init = DoSomeOperationSetup();
       StartSomeOperation(init);
    }
    ...
    string DoSomeOperationSetup()
    {
       DoSomeSetupTasks();

       MessageBox.Show("We are starting an operation");

       string initValue;
       initValue = GetSomeStringValue();
       return initValue;
    }  
    ...
}

In this case the original Windows Phone Silverlight program blocks the execution of the program while showing the "We are starting an operation" message box.

Once the user clicks the 'Ok' button the execution resumes in the following line. As displayed in the following picture:

UI Execution break

In order to archive the same functionallity on Windows UWP we need to use the MessageDialog.ShowAsync operation.

This operation requires several changes to the code. The following code snippet shows the changes:

-- Windows UWP --

partial class MyPage ...
{
    ...
    private async void OnClick(object sender, RoutedEventArgs e)
    {
       var init = await DoSomeOperationSetup();
       StartSomeOperation(init);
    }
    ...

    async Task<string> DoSomeOperationSetup()
    {
      DoSomeSetupTasks();

      await (new MessageDialog("We are starting an operation")).ShowAsync();
      string initValue;
      initValue = GetSomeStringValue();
      return initValue;
    }  
    ...
}

In order to archive this conversion we need to do the following changes:

  1. Change the signature of the MyPage.OnClick to include the async keyword
  2. Change the DoSomeOperationSetup signature to include the async signature and the return type to be Task<string> instead of just string.
  3. Add the await keyword to the invocations of the DoSomeOperationSetup method
  4. Change the call to the MessageBox.Show method to be a new MessageDialog("...").ShowAsync invocation

Conversion

he first thing we need to define is a mapping for the System.Windows.Controls.MessageBox class. And also specify that the equivalent member need async conversion.

-- UWP Conversion tool code mapping --

<MapUnit xmlns="clr-namespace:Mobilize.Mappers.Extensibility.Core;assembly=Mobilize.ExtensibleMappers"
         xmlns:map="clr-namespace:Mobilize.Mappers.Extensibility.Code;assembly=Mobilize.ExtensibleMappers">
  <MapUnit.Elements>
    <map:CodeMapPackage Type="System.Windows.MessageBox">
      <map:CodeMapPackage.Maps>
        <map:CodeMap Kind="Call" MemberName="Show">
          <map:Conditional>
            <map:Case>
              <map:Case.Condition>
                <map:WithMethodCall>
                  <map:ArgumentCount>1</map:ArgumentCount>
                  <map:WithArgument Position="0">
                    <map:AssignName>$message</map:AssignName>
                  </map:WithArgument>
                </map:WithMethodCall>
              </map:Case.Condition>
              <map:Case.Action>
                <map:ReplaceWithTemplate>
                  await (new Windows.UI.Popups.MessageDialog($message)).ShowAsync()
                </map:ReplaceWithTemplate>
              </map:Case.Action>
            </map:Case>
            ...
          </map:Conditional>
        </map:CodeMap>
      </map:CodeMapPackage.Maps>
      <map:CodeMapPackage.Metadata>
        <map:PackageMetadata Key="ASYNC_MEMBERS" Value="Show"/>
      </map:CodeMapPackage.Metadata>
    </map:CodeMapPackage>
  </MapUnit.Elements>
</MapUnit>

By specifying the ASYNC_MEMBERS metadata value we enable instruct the conversion tool to apply async changes to the intermediate method calls between the event handler to the point where the async method invocation is being made.

Also this mapping uses a Conditional mapping which is described in detail on [Writing case-based conditional mappings](Writing case-based conditional mappings).

Overview

Writing mappings

Code Mapping Actions

Code Mapping Conditions

XAML mapping actions

XAML mapping conditions

Misc

Clone this wiki locally