表单中的嵌套异步和等待
Nested Async and Await in Forms
我在 Mac Mini 上使用 Xamarin Forms 和 Xamarin Studio,我遇到了一个 async/await 问题,希望有人能帮助解决。我有一个按钮点击事件定义为:
void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
this.HandleSignInCompleted(..);
}
然后调用一个方法来进行一些用户配置文件初始化,它需要联系服务器:
async void HandleSignInCompleted(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
无论 ConfigureAwait
是否存在,这都会无限期地等待。简单的用户配置文件服务现在执行以下操作(仅 returns 我自己进行测试):
public async Task<UserProfile> GetAsync()
{
//wrapper around app properties
var accessToken = (string)_appProperties.Get ("token");
//Tried with ConfigureAwait and without
await Task.Delay (100);
//TODO:replace with facebook load
return new UserProfile (..);
}
ConfigureAwait(false)
、Task.Delay
个扼流圈。没有它,它可以工作,但调试器崩溃了。这是怎么回事,我该如何解决这个问题,以便 AJAX 请求(当我将来在用户配置文件服务中替换它时)能够正常工作?
同步优于异步是一种反模式;您不仅受制于您自己的代码(必须在所有地方使用 ConfigureAwait(false)
),而且受制于您调用的任何库。特别是,我 运行 过去在 Xamarin 上遇到过关于 Task.Delay
的类似问题。在您尝试将其切换为真正的网络呼叫之前,HttpClient
在某些移动平台上存在相同的问题(iOS 或 Android,不记得 ATM 了)。不确定 Facebook 是否会有类似的错误。
所以,总而言之,你真的不能那样做。而是一路拥抱async
:
async Task HandleSignInCompletedAsync(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
}
async void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
await this.HandleSignInCompletedAsync(..);
}
必要时禁用控件,但不要阻止。这种方法的一个很好的副作用是您的应用总是响应更快。
我在 Mac Mini 上使用 Xamarin Forms 和 Xamarin Studio,我遇到了一个 async/await 问题,希望有人能帮助解决。我有一个按钮点击事件定义为:
void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
this.HandleSignInCompleted(..);
}
然后调用一个方法来进行一些用户配置文件初始化,它需要联系服务器:
async void HandleSignInCompleted(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
无论 ConfigureAwait
是否存在,这都会无限期地等待。简单的用户配置文件服务现在执行以下操作(仅 returns 我自己进行测试):
public async Task<UserProfile> GetAsync()
{
//wrapper around app properties
var accessToken = (string)_appProperties.Get ("token");
//Tried with ConfigureAwait and without
await Task.Delay (100);
//TODO:replace with facebook load
return new UserProfile (..);
}
ConfigureAwait(false)
、Task.Delay
个扼流圈。没有它,它可以工作,但调试器崩溃了。这是怎么回事,我该如何解决这个问题,以便 AJAX 请求(当我将来在用户配置文件服务中替换它时)能够正常工作?
同步优于异步是一种反模式;您不仅受制于您自己的代码(必须在所有地方使用 ConfigureAwait(false)
),而且受制于您调用的任何库。特别是,我 运行 过去在 Xamarin 上遇到过关于 Task.Delay
的类似问题。在您尝试将其切换为真正的网络呼叫之前,HttpClient
在某些移动平台上存在相同的问题(iOS 或 Android,不记得 ATM 了)。不确定 Facebook 是否会有类似的错误。
所以,总而言之,你真的不能那样做。而是一路拥抱async
:
async Task HandleSignInCompletedAsync(..)
{
var profile = await _profileService.GetAsync ().ConfigureAwait(false);
}
async void LoginButton_Clicked (object sender, EventArgs e)
{
//Do some stuff
await this.HandleSignInCompletedAsync(..);
}
必要时禁用控件,但不要阻止。这种方法的一个很好的副作用是您的应用总是响应更快。