-
Notifications
You must be signed in to change notification settings - Fork 5
Problematic Async conversion scenarios
There are some scenarios not supported by the Silverlight to UWP conversion async conversion. As described in the Writing a mapping from a synchronous member to an asynchronous member document the conversion tool will try to change the code by adding async/await keywords if an API changed from a synchronous to a asynchronous version.
This conversion could not be applied in the following scenarios:
After the conversion asynchronous code could end up being invoked on a constructor .
An example of this scenario is the following:
-- Windows Phone Silverlight --
public class ClassWithProblematicConstructor
{
int x;
public ClassWithProblematicConstructor()
{
x = 100;
if (x > 10)
{
MessageBox.Show("????");
}
}
}
This code uses the MessageBox.Show
method which is now converted to an async operation.
When converting this code to UWP the converter generates the following code:
-- UWP --
public class ClassWithProblematicConstructor
{
int x;
#error WINDOWS_PHONE_SL_TO_UWP: (1212) Async conversion could not be applied to constructors. Constructor name : 'ClassWithProblematicConstructor'
public ClassWithProblematicConstructor()
{
x = 100;
if ( x > 10 )
{
await (new Windows.UI.Popups.MessageDialog("????")).ShowAsync();
}
}
In this case the conversion tool generates a #error directive To instruct the user that this code requires manual changes to solve this issue.
A solution for this problem is to move the code that is now asynchronous to an initialization method. However how this solution is applied depends on how this class is instantiated. For example the constructor may be a control instantiated in XAML or code instantiated by using reflection.
After the conversion a property getter or setter may now have code that is asynchronous.
-- Windows Phone Silverlight --
class ClassWithProblematicProperty
{
public int Xoo
{
get
{
if (DateTime.Now > DateTime.Now - TimeSpan.FromDays(1))
{
MessageBox.Show("S");
}
return innerValue;
}
set
{
innerValue = value;
}
}
public int innerValue;
}
When converting this code, the conversion tool generates the following class:
class Problematicproperty
{
#error WINDOWS_PHONE_SL_TO_UWP: (1211) Async conversion could not be applied to property definitions. Property name : 'Xoo'
public int Xoo
{
get
{
if ( DateTime.Now > DateTime.Now - TimeSpan.FromDays(1) )
{
await (new Windows.UI.Popups.MessageDialog("S")).ShowAsync();
}
return innerValue;
}
set
{
innerValue = value;
}
}
public int innerValue;
}
In this case the conversion tool generates a #error directive to instruct the user that this code requires manual changes to solve this issue.
There are several possible solutions for this problem. For example:
- Create a
GetXYZ
andSetXYZ
methods instead of using a property - Move the asynchronous code to a separate method
- Execute the code in a separate task (without awaiting it)
However these solutions depend on how the code is structured. For example the property definition may be part of the implementation of a contract.
After the conversion a method that was overriding another may now have code that is asynchronous.
If the method's return type is not void
, we need to change the signature to make it return Task<T>
instead of the current type. By doing so we would generate a compilation problem.
-- Windows Phone Silverlight --
public class MySubClassOverwritting : MyParentClass
{
public override int Go()
{
MessageBox.Show("Hello");
return 10 * 39;
}
}
When converting this code, the conversion tool generates the following class:
public class MySubClassOverwritting
: MyParentClass
{
#error WINDOWS_PHONE_SL_TO_UWP: (1201) Async conversion could not be applied to virtual methods being overridden.Method name:'Go'
public override int Go()
{
await (new Windows.UI.Popups.MessageDialog("Hello")).ShowAsync();
return 10 * 39;
}
}
In this case the conversion tool generates a #error directive to instruct the user that this code requires manual changes to solve this issue.
As with the other cases the solution for this problem depends on the code required for these classes. Possible solutions may include:
- Change the signature of the base class (if it's part of the source code) and of all its siblings and descendants
- Move the asynchronous code to another method
- Execute the code without
awaiting
it
All these solutions may or may not apply to a specific class.
Recommended reading:
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