Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 表单中嵌套的异步和等待_C#_Android_Xamarin_Xamarin.forms_Xamarin Studio - Fatal编程技术网

C# 表单中嵌套的异步和等待

C# 表单中嵌套的异步和等待,c#,android,xamarin,xamarin.forms,xamarin-studio,C#,Android,Xamarin,Xamarin.forms,Xamarin Studio,我在Mac Mini上与Xamarin Studio一起使用Xamarin表单,我遇到了一个异步/等待问题,我希望有人能帮助解决这个问题。我有一个按钮点击事件,定义为: void LoginButton_Clicked (object sender, EventArgs e) { //Do some stuff this.HandleSignInCompleted(..); } 然后调用一个方法进行一些用户配置文件初始化,它需要与服务器联系: async void HandleSign

我在Mac Mini上与Xamarin Studio一起使用Xamarin表单,我遇到了一个异步/等待问题,我希望有人能帮助解决这个问题。我有一个按钮点击事件,定义为:

void LoginButton_Clicked (object sender, EventArgs e)
{
  //Do some stuff
  this.HandleSignInCompleted(..);
}
然后调用一个方法进行一些用户配置文件初始化,它需要与服务器联系:

async void HandleSignInCompleted(..)
{
  var profile = await _profileService.GetAsync ().ConfigureAwait(false);
无论是否存在
configurewait
,此操作都会无限期等待。user profile service simple现在执行以下操作(只返回自己进行测试):

公共异步任务GetAsync() { //包装应用程序属性 var accessToken=(字符串)_appProperties.Get(“token”); //使用ConfigureWait和不使用进行了尝试 等待任务。延迟(100); //TODO:替换为facebook加载 返回新的用户配置文件(…); }
使用
ConfigureAwait(false)
任务。延迟
阻塞。没有它,它可以工作,但调试器崩溃了。发生了什么以及如何解决此问题,以便AJAX请求(将来在用户配置文件服务中替换它时)能够正常工作?

异步同步是一种反模式;您不仅受制于自己的代码(必须在任何地方使用
ConfigureAwait(false)
),还受制于您调用的任何库。特别是,过去我在Xamarin上遇到过类似的问题,关于
Task.Delay
。在您尝试将其切换到真正的网络呼叫之前,
HttpClient
在某些移动平台上也存在同样的问题(iOS或Android,不记得ATM)。不确定Facebook是否会有类似的bug

总之,你真的不能这么做。相反,一路拥抱
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(..);
}

如果必须,请禁用控件,但不要阻止。这种方法的一个很好的副作用是,您的应用程序总是更具响应性。

稍微无关:您在异步方法中使用了一个void(请注意事件处理程序的例外情况)。也许可以根据指导原则将其更改为Task:谢谢,这很有意义。何时使用configureawait,何时不使用configureawait,是否有理由?它似乎没有太多的文档,只是这是一个绕过这类问题的技巧?
ConfigureAwait(false)
是一种优化,可以在
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(..);
}