Skip to content

Problematic Async conversion scenarios

ldfallas edited this page Oct 7, 2015 · 1 revision

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:

1. A constructor invokes code that is now async

Problem

After the conversion asynchronous code could end up being invoked on a constructor .

Example

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.

Possible solution

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.


2. A property/indexer getter or setter invokes code that is now async

Problem

After the conversion a property getter or setter may now have code that is asynchronous.

Example

-- 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.

Possible solution

There are several possible solutions for this problem. For example:

  • Create a GetXYZ and SetXYZ 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.


3. A method that is overriding another is now async

Problem

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.

Example

-- 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.

Possible solution

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:

Overview

Writing mappings

Code Mapping Actions

Code Mapping Conditions

XAML mapping actions

XAML mapping conditions

Misc

Clone this wiki locally