在PCL中使用Mono Droid的Microsoft.bcl.async?

时间:2013-01-31 17:37:40

标签: xamarin.android portable-class-library

我有一个针对Profile158的便携式类库(PCL)(Windows应用商店,.NET 4.5,Silverlight 5,Windows Phone 8)。我可以轻松地使用返回一种Task类型的方法,并且它都可以像我期望的那样工作。每当我访问Result属性时,它就会完成运行异步代码并返回结果。

但是,如果我在PCL中的方法中使用async / await关键字,我会得到一个任务。但是,当我尝试访问Result属性时,它会阻塞并且永远不会返回。

在两种情况下查看Visual Studio中的调试输出窗口,我看到相同的文本:

Thread started: 
Thread started: 
Loaded assembly: Mono.Security.dll [External]
Thread started: 
Thread started: 

因此看起来好像代码正在运行,但它永远不会返回到UI线程。有没有其他人试图在PCL中使用带有Microsoft.bcl.async的PCL?

我的Mono Droid项目针对的是Android 2.1。

谢谢,    - 约翰

更新
以下是有关不同方案的一些其他信息。首先,这里是在UI代码中编写的适用于Mono Droid的代码:

var task = request.GetResponseAsync();
string html = task.Result.GetResponseText();

然后我在PCL中创建了以下方法:

public async Task<string> Test()
{
    IHttpResponse responce = await GetResponseAsync();
    return responce.GetResponseText();
}

使用Mono UI代码中的代码调用它:

string html = request.Test().Result;

它永远不会回来......

1 个答案:

答案 0 :(得分:3)

这是classic deadlock scenario,正如我在博客中描述的那样。

默认情况下,await会捕获“上下文”并使用它来恢复async方法。除非是SynchronizationContext,否

因此,您从UI线程(提供null)调用TaskScheduler方法,然后通过调用async来阻止UI线程。 SynchronizationContext方法无法完成,因为它试图在UI线程上完成,该线程被阻止。

要解决此问题,请遵循以下准则:

  1. 一直使用Result。不要在async方法返回的async上致电ResultWait;请改用Task
  2. 尽可能在库代码中使用async
  3. 您可能还会发现我的async/await intro有帮助。