XamlReader.Load() Marshalled

2

I'm trying to generate my own custom tile from xaml. I've converted some code from C++ to C# in order to integrate it into my app.

Basically I've got this method:

async Task GenerateHighResTileImage(string inputMarkupFilename, string outputImageFilename, Size size)
{
     StorageFolder assetsFolder = await Package.Current.InstalledLocation.GetFolderAsync("Assets");
     StorageFile markupStorageFile = await assetsFolder.GetFileAsync(inputMarkupFilename);
     string markupContent = await FileIO.ReadTextAsync(markupStorageFile);

     Border grid = (Border)XamlReader.Load(markupContent);
     await RenderAndSaveToFileAsync(grid, outputImageFilename, (int)size.Width, (int)size.Height);
}

The debugger halts on the line where I'm trying to load the markup saying:

A first chance exception of type 'System.Exception' occurred in BGTask.winmd

Additional information: The application called an interface that was marshalled for a different thread. (Exception from HRESULT: 0x8001010E (RPC_E_WRONG_THREAD))

My tile is very plain, as I'm just testing:

<Border Height="360" Width="360" Padding="12" BorderBrush="White" BorderThickness="4" CornerRadius="2" Background="#00b2f0" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
</Border>

And it is able to successfully load it in the markupContent string.

The code looks like this in C++

task<void> AppTileUpdater::GenerateHighResTileImageUpdateAsync(String^ inputMarkupFilename, String^ outputImageFilename, Size size)
{
    return create_task(Package::Current->InstalledLocation->GetFolderAsync("Assets"))
        .then([inputMarkupFilename](StorageFolder^ assetsFolder) ->IAsyncOperation<StorageFile^>^ {
        return assetsFolder->GetFileAsync(inputMarkupFilename);
    }).then([](StorageFile^ markupStorageFile)  ->IAsyncOperation<Platform::String^>^ {
        return FileIO::ReadTextAsync(markupStorageFile);
    }).then([this, outputImageFilename, size](Platform::String^ markupContent){
          Border^ border = (Border^) XamlReader::Load(markupContent);

          return RenderAndSaveToFileAsync(border, outputImageFilename, (unsigned int) size.Width, (unsigned int) size.Height);
    });
}

Am I missing something?

Edit The method is being run from the Run method

async public void Run(IBackgroundTaskInstance taskInstance)
{
    var deferral = taskInstance.GetDeferral();
    taskInstance.Canceled += (s, e) => { };
    taskInstance.Progress = 0;

    await GenerateHighResTileImage("150x150Tile.xml", "updatedTile.png", new Size(150, 150));
    UpdateTile("updatedTile.png");

    deferral.Complete();

}

The code also works fine when I run it outside the BackgroundTask

c#
c++
xaml
windows-phone-8.1
asked on Stack Overflow Jan 4, 2015 by Jazerix • edited Jan 4, 2015 by Jazerix

1 Answer

1

If you are using Silverlight, then you will need to run your code from the default dispatcher[Deployment.Current.Dispatcher.BeginInvoke(...)]. If you are using a Universal App, you need to derive from the XamlRenderingBackgroundTask but it is highly recommended you use C++ to avoid running out of memory.

answered on Stack Overflow Jan 5, 2015 by Peter Torr - MSFT

User contributions licensed under CC BY-SA 3.0