"Unknown Runtime Error" when using Windows Runtime Component with Javascript UWP App

8

I'm trying to use a Windows Runtime Component to provide interoperability between my Javascript UWP app and C# logic that I've written. If I set the minimum version to Fall Creator's Update (build 16299, needed to use .NET Standard 2.0 libraries), I get the following error when trying to call a simple method:

Unhandled exception at line 3, column 1 in ms-appx://ed2ecf36-be42-4c35-af69-93ec1f21c283/js/main.js
0x80131040 - JavaScript runtime error: Unknown runtime error

If I run this code using Creator's Update (15063) as the minimum, then the code runs fine.

I've created a Github repo containing a sample solution that generates the error for me when running locally.

Here's what main.js looks like. The error occurs when trying to run the getExample function:

// Your code here!

var test = new RuntimeComponent1.Class1;

test.getExample().then(result => {
    console.log(result);
});

This is what Class1.cs looks like:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;

namespace RuntimeComponent1
{
    public sealed class Class1
    {
        public IAsyncOperation<string> GetExample()
        {
            return AsyncInfo.Run(token => Task.Run(getExample));
        }

        private async Task<string> getExample()
        {
            return "It's working";
        }
    }
}

I can't think of a much simpler test case than that - I have no NuGet packages installed or anything like that. I have no idea what might be causing this. Anyone else have ideas?

c#
uwp
windows-runtime
win-universal-app
winjs
asked on Stack Overflow Jun 29, 2018 by Jim Cloudman

2 Answers

1

There is nothing actually async about this function, even as a simplified example

private async Task<string> getExample()
{
    return "It's working";
}

Also if the said function is already return a Task then there is no need to wrap it in Task.Run here

return AsyncInfo.Run(token => Task.Run(getExample));

Refactor the code to follow advised syntax

public sealed class Class1 {
    public IAsyncOperation<string> GetExampleAsync() {
        return AsyncInfo.Run(token => getExampleCore());
    }

    private Task<string> getExampleCore() {
        return Task.FromResult("It's working");
    }
}

Since there is nothing to be awaited, use Task.FromResult to return the Task<string> from the private getExampleCore() function.

Do note also that because the original functions were returning unstarted tasks, that this causes an InvalidOperationException to be thrown by AsyncInfo.Run<TResult>(Func<CancellationToken, Task<TResult>>) Method

You can also consider taking advantage of the AsAsyncOperation<TResult> extension method, given the simple definition of the called function.

public IAsyncOperation<string> GetExampleAsync() {
    return getExampleCore().AsAsyncOperation();
}

And invoked in JavaScript

var test = new RuntimeComponent1.Class1;

var result = test.getExampleAsync().then(
    function(stringResult) {
        console.log(stringResult);
    });
answered on Stack Overflow Jul 7, 2018 by Nkosi • edited Jul 7, 2018 by Nkosi
0

This is not proper async method:

private async Task<string> getExample()
{
    return "It's working";
}

The reason for this is that it was supposed to return Task<string>, not just string.

So, you should change it to:

private async Task<string> getExample()
{
    return Task.FromResult("It's working");
}
answered on Stack Overflow Jul 8, 2018 by Mihir Dave • edited Jul 10, 2018 by Robert Columbia

User contributions licensed under CC BY-SA 3.0