-
Notifications
You must be signed in to change notification settings - Fork 5
Writing a mapping from a synchronous member to an asynchronous member
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:
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:
- Change the signature of the MyPage.OnClick to include the
async
keyword - Change the
DoSomeOperationSetup
signature to include theasync
signature and the return type to beTask<string>
instead of juststring
. - Add the
await
keyword to the invocations of theDoSomeOperationSetup
method - Change the call to the
MessageBox.Show
method to be anew MessageDialog("...").ShowAsync
invocation
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).
Contact us for more information
Overview
Writing mappings
Code Mapping Actions
- ActionSequence
- AddHelper
- AddNamespaceImport
- AddPreStatementFromTemplate
- CommentOut
- Conditional
- Keep Code Mapping Action
- MarkAsNotMapped
- RedirectCall
- RedirectCallToInnerMember
- RedirectIndexer
- RedirectProperty
- RemoveCurrentStatement
- RemoveParameter
- ReplaceClassUsage
- ReplaceMethodBodyWithTemplate
- ReplaceParameterDeclarationType
- ReplaceParameterMember
- ReplaceParameterValue
- ReplaceWithMethodCall
- ReplaceWithProperty
- ReplaceWithTemplate
Code Mapping Conditions
- AllConditionsApply
- ArgumentCount
- AssignName
- AssignNameToArgumentRange
- IsExpressionOfType
- IsStringLiteralMatchingRegex
- WithArgument
- WithAssignment
- WithAssignmentLeftSide
- WithAssignmentRightSide
- WithCalledMemberOwner
- WithCalledMethodExpression
- WithConstructorCall
- WithLambdaExpressionBody
- WithLambdaExpressionParameter
- WithLeftSideOfDottedAccess
- WithMemberInitValue
- WithMethodCall
XAML mapping actions
- ActionSequence
- AddStatementToConstructorFromTemplate
- BindPropertyValueElement Xaml mapping action
- ChangeEventHandlerEventArgsType
- CommentOutElement
- CommentOutProperty
- MarkAsNotMapped
- MoveValueToContentProperty
- RemoveNamespaceDeclaration
- RenameElement
- RenameProperty
- ReplaceAttributeValue
- ReplaceEventHandlerBodyWithTemplate
- ReplaceEventHandlerParameterMember
- ReplaceNamespaceDeclaration
- ReplacePropertyValueWithParentResource
- ReplaceStaticResourceWithThemeResource
- SetPropertyValueToComplexElement
- SetPropertyValueToSimpleValue
- WrapContent
XAML mapping conditions
Misc