我有一个针对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;
它永远不会回来......
答案 0 :(得分:3)
这是classic deadlock scenario,正如我在博客中描述的那样。
默认情况下,await
会捕获“上下文”并使用它来恢复async
方法。除非是SynchronizationContext
,否
因此,您从UI线程(提供null
)调用TaskScheduler
方法,然后通过调用async
来阻止UI线程。 SynchronizationContext
方法无法完成,因为它试图在UI线程上完成,该线程被阻止。
要解决此问题,请遵循以下准则:
Result
。不要在async
方法返回的async
上致电Result
或Wait
;请改用Task
。async
。您可能还会发现我的async
/await
intro有帮助。