Joh*_*oha 5 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:
Run Code Online (Sandbox Code Playgroud)
所以看起来好像代码正在运行,但它永远不会返回到UI线程.有没有其他人试图在PCL中使用带有Microsoft.bcl.async的PCL?
我的Mono Droid项目针对的是Android 2.1.
谢谢, - 约翰
更新:
以下是有关不同方案的一些其他信息.首先,这里是在UI代码中编写时可以在Mono Droid上运行的代码:
var task = request.GetResponseAsync();
string html = task.Result.GetResponseText();
Run Code Online (Sandbox Code Playgroud)
然后我在PCL中创建了以下方法:
public async Task<string> Test()
{
IHttpResponse responce = await GetResponseAsync();
return responce.GetResponseText();
}
Run Code Online (Sandbox Code Playgroud)
并使用Mono UI代码中的代码调用它:
string html = request.Test().Result;
Run Code Online (Sandbox Code Playgroud)
它永远不会回归......
正如我在博客中所描述的,这是一个典型的死锁场景。
默认情况下,await将捕获“上下文”并使用它来恢复该async方法。这个“上下文”是当前的,SynchronizationContext除非它是null,在这种情况下它是当前的TaskScheduler。
因此,您async从 UI 线程(提供SynchronizationContext)调用一个方法,然后通过调用 来阻塞 UI 线程Result。该async方法无法完成,因为它正在尝试在 UI 线程上完成,而该线程已被阻止。
要解决此问题,请遵循以下准则:
async一直往下使用。不要对方法返回的值调用Resultor ;代替使用。WaitTaskasyncawaitConfigureAwait(false)尽可能在您的库代码中使用。您可能还会发现我的async/await介绍很有帮助。
| 归档时间: |
|
| 查看次数: |
1061 次 |
| 最近记录: |