从Windows运行时组件调用可移植代码库中的异步方法

时间:2012-11-29 18:05:43

标签: javascript windows-runtime portable-class-library winrt-async

背景

我正在构建一个可在Windows 8(作为商店应用)和Windows 7(作为WPF桌面应用)上使用的应用。这些应用程序将允许浏览一堆(大约500多个应用程序“页面”)的内容。

虽然我无法在它们之间共享大部分代码,但我确实希望尽可能地分享。所以我创建了一个面向.NET 4.5,Silverlight 4+和Windows 8的可移植代码库(PCL)。由于Win 8应用程序是用JavaScript编写的(出于各种原因,不是这个问题的一部分),我还有一个Windows运行时组件,充当JavaScript和PCL之间的代理。换句话说,来自JavaScript的异步调用首先在WinRT组件上调用一个方法,然后在PCL中调用相应的方法。

问题

为了支持PCL中的异步操作,我通过NuGet安装了Microsoft.Bcl和Microsoft.Bcl.Async软件包。除其他外,这些限定了任务和任务<>异步方法所必需的类,但它们在自己的程序集中这样做。 WinRT组件不需要那些库作为任务和任务<>已经为它定义了。问题是当我在WinRT组件中添加代码以在PCL中调用Async方法时返回Task<>对象,我得到以下构建错误:

  

WINMDEXP:错误WME1007:无法解析引用'Assembly(Name = System.Threading.Tasks,Version = 1.5.11.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a)'。

我尝试过什么

我尝试了很多东西,但可能出现的主要两个是:

  1. 修改WinRT组件的app.Config,为程序集添加bindingRedirect。
  2. 通过从内部执行的异步调用中获取Task对象并在其上调用Wait(),使外部非异步PCL调用。等待或者永远不会回来引发一个神秘的异常。
  3. 那么,有关如何实现这一目标的任何想法吗?

    谢谢,
    戴夫帕克

2 个答案:

答案 0 :(得分:0)

这是WinMDExp的已知问题,已在Visual Studio 2013中修复。

我们在此页面上提供了一种解决方法(请参阅问题7):http://blogs.msdn.com/b/bclteam/p/asynctargetingpackkb.aspx

答案 1 :(得分:-1)

Windows运行时组件是针对Windows运行时子集的特殊类型的项目,可用于使用JavaScript,C#和C ++编写的Windows应用商店。它们还需要特定类型的类和属性,例如要密封的所有公共类,没有公共字段,没有返回Task的公共方法,只有IAsyncAction或IAsyncOperation ...
您可以在其中引用可移植类库,但有一些限制。

已修改:要解决您的问题,您不能在Windows运行时组件中返回任何非WinRT类型 - 您无法从可移植库中返回任何类型,您必须创建包装类型。 /> 您也无法返回任务和任务类型,因为它们不是WinRT类型,但您可以创建包装器方法并返回正确的等待类型,如下所示:

public IAsyncAction DoActionAsync()
{
    return DoAsync().AsAsyncAction();
}

internal async Task DoAsync()
{
}

public IAsyncOperation<int> DoIntOperationAsync()
{
    return DoIntAsync().AsAsyncOperation();
}

internal async Task<int> DoIntAsync()
{
    return 42;
}