2

背景

我構建的應用程序可在Windows 8(作爲商店應用程序)和Windows 7(作爲WPF桌面應用程序)上使用。這些應用程序將允許瀏覽大量內容(大約500多個應用程序「頁面」)。從Windows運行時組件調用便攜式代碼庫中的異步方法

雖然我無法分享他們之間的大部分代碼,但我確實希望儘可能多地分享。因此,我創建了一個面向.NET 4.5,Silverlight 4+和Windows 8的可移植代碼庫(PCL)。由於Win 8應用程序是用JavaScript編寫的(出於各種原因,不屬於此問題的一部分),我也有Windows運行時組件,充當JavaScript和PCL之間的代理。換句話說,來自JavaScript的異步調用首先在WinRT組件上調用一個方法,WinRT組件然後調用PCL中的相應方法。

問題

爲了支持在PCL異步操作,我通過的NuGet安裝Microsoft.Bcl和Microsoft.Bcl.Async包。除其他外,這些定義了異步方法所需的任務和任務類,但是它們在它們自己的程序集中這樣做。 WinRT組件不需要這些庫,因爲已經爲它定義了任務和任務<>。問題是,當我在WinRT的組件添加代碼來調用返回一個任務<>對象,我得到下面的生成錯誤的PCL異步方法:

WINMDEXP : error WME1007: Could not resolve reference 'Assembly(Name=System.Threading.Tasks, Version=1.5.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a)'.

我曾嘗試

我試過很多東西,但一個可能出現的兩個主要有:

  1. 修改的app.config爲WinRT的組件添加bindingRedirect的裝配。
  2. 通過將Task對象從內部執行的異步調用中取回並對其調用Wait(),使外部調用PCL非異步。等待永遠不會返回拋出一個神祕的例外。

那麼,有關如何做到這一點的想法?

謝謝,
戴夫·帕克

回答

-1

Windows運行時組件是特殊類型的目標可以用JavaScript編寫的,C#和C++的Windows Store應用程序Windows運行時的子集的項目。並且它們還需要特定類型的類和屬性,像所有要被封裝的公共類,沒有公共類,沒有公共方法返回任務,只有IAsyncAction或IAsyncOperation ...
您可以在其中引用您的可移植類庫,但有一些限制。

編輯:要解決您的問題,您不能在Windows運行時組件中返回任何非WinRT類型 - 不能從便攜庫返回任何類型,您必須創建包裝類型。
您也不能返回任務和任務類型,因爲這些都不是WinRT的類型,但你可以創建包裝方法和返回正確的awaitable類型是這樣的:

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

internal async Task DoAsync() 
{ 
} 

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

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

實際上Windows運行時組件可以引用PCL就好了。我已經這樣做了。 –

+0

你是對的,你可以參考便攜式庫有一些限制,但不是在任何地方。在後臺任務中,您只能使用純粹的Windows運行時組件。 –

+0

要麼我誤解你的回答,要麼你誤解了我的問題。我的問題不是從WRC返回,而是從WRC調用PCL中的異步方法。在PCL中,Task <>由CodePlex的Microsoft.Bcl。*庫實現。在WRC任務<>中內置了.NET Framework的WinRT子集。編譯器不能將它們轉換爲任何通用的基礎。此外,IAsynAction和IAsyncOperation在Windows.Foundation命名空間(WinRT的一部分)中定義,因此不適用於PCL。如果你的迴應以某種方式解決這個問題,我沒有看到它。 –