将Windows运行时组件与Javascript UWP App一起使用时,出现“未知的运行时错误”

时间:2018-06-29 04:37:31

标签: c# uwp windows-runtime win-universal-app winjs

我正在尝试使用Windows运行时组件在Javascript UWP应用和我编写的C#逻辑之间提供互操作性。如果将最低版本设置为Fall Creator's Update(内部版本16299,需要使用.NET Standard 2.0库),则在尝试调用简单方法时会出现以下错误:

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

如果我至少使用创建者更新(15063)运行此代码,则该代码可以正常运行。

我创建了一个Github repo,其中包含一个示例解决方案,该解决方案在本地运行时会为我生成错误。

这是main.js的样子。尝试运行getExample函数时发生错误:

// Your code here!

var test = new RuntimeComponent1.Class1;

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

这是Class1.cs的样子:

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";
        }
    }
}

我想不出比这简单得多的测试用例-我没有安装NuGet软件包或类似的东西。我不知道是什么原因造成的。其他人有想法吗?

2 个答案:

答案 0 :(得分:1)

即使作为一个简化示例,该功能实际上也没有异步

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

如果上述函数已经返回了Task,则无需在此处将其包装在Task.Run

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

重构代码以遵循建议的语法

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

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

由于没有什么可等待的,请使用Task.FromResult从私有Task<string>函数返回getExampleCore()

还要注意,由于原始函数正在返回未启动的任务,因此这会导致AsyncInfo.Run<TResult>(Func<CancellationToken, Task<TResult>>) Method抛出InvalidOperationException

考虑到被调用函数的简单定义,您还可以考虑利用AsAsyncOperation<TResult>扩展方法。

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

并在JavaScript中调用

var test = new RuntimeComponent1.Class1;

var result = test.getExampleAsync().then(
    function(stringResult) {
        console.log(stringResult);
    });

答案 1 :(得分:0)

这不是正确的异步方法:

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

之所以这样做,是因为它应该返回Task<string>,而不仅仅是string

因此,您应该将其更改为:

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