从 Google 获取用户个人资料时应用停止响应

App stops responding while getting user profile from Google

我尝试使用 Google .NET API 来获取经过验证的用户电子邮件,但应用程序停止响应我用 **** 标记的行。我第一次 运行 它打开浏览器并询问我的 GMAIL,在选择 gmail 后它说现在你可以关闭浏览器 window,但我的桌面应用程序将停止响应。下次我 运行 应用程序它只是停止响应,除非我从 AppData\Roaming 中删除 Google.Apis.Auth 文件夹:

        private async Task VerifyEmail()
        {
            UserCredential credential;
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                new ClientSecrets
                {
                    ClientId = "xxxx.apps.googleusercontent.com",
                    ClientSecret = "xxxx-xxxxx"
                },
                new[] { Google.Apis.Oauth2.v2.Oauth2Service.Scope.UserinfoEmail },
                "user",
                CancellationToken.None,
                new FileDataStore("My.DataStore")
                );

            var initializer =
        new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential,
            ApplicationName = "My App",
        };
            var oauthSerivce = new Google.Apis.Oauth2.v2.Oauth2Service(initializer);

            // app stops responding here **** :
            var userInfo = await oauthSerivce.Userinfo.Get().ExecuteAsync();
            MessageBox.Show(userInfo.Email);
        }

这个问题的大部分内容都在评论里,所以我总结如下:

it has .Result, same as await.

.Resultawait 不同。 await 将调用标记为 async 并告诉 .Net 在异步上下文中 运行 此调用,而不会阻塞。 .Result 阻塞线程并尝试获取结果。你应该(大部分)永远不要像这样阻塞异步代码,查看 Stephen Cleary 的博客 Don't Block on Async Code

added await (in question above too), still deadlock. :|

async 代码需要在 async 上下文中调用。因此,您还必须使所有父方法都异步。 You can use a thread pool thread to get around this。但最好的解决方案是进行所有以前的方法调用 async。这确实意味着 async 倾向于通过您的代码库传播,但这是野兽的本性。