.net MSAL。WPF应用程序冻结
任务:我需要通过单独的WPF窗口创建一个交互式登录,MSAL(Microsoft.Identity.Client)必须显示该窗口。 解决方案:下面的代码应该可以解决我的任务.net MSAL。WPF应用程序冻结,.net,wpf,multithreading,msal,.net,Wpf,Multithreading,Msal,任务:我需要通过单独的WPF窗口创建一个交互式登录,MSAL(Microsoft.Identity.Client)必须显示该窗口。 解决方案:下面的代码应该可以解决我的任务 IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.CreateWithApplicationOptions(_publicClientApplicationOptions).WithDef
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.CreateWithApplicationOptions(_publicClientApplicationOptions).WithDefaultRedirectUri().Build();
byte[] exchangeCache = null;
publicClientApplication.UserTokenCache.SetAfterAccess(tokenCacheArgs =>
{
exchangeCache = tokenCacheArgs.TokenCache.SerializeMsalV3();
});
AuthenticationResult result = null;
Task<AuthenticationResult> task = publicClientApplication.AcquireTokenInteractive(_ewsScopes).WithParentActivityOrWindow(GetWindowHandle()).ExecuteAsync();
result = task.Result; // this line gots freeze
您应该异步执行任务,而不是访问blockingResult
属性:
AuthenticationResult result = await publicClientApplication
.AcquireTokenInteractive(_ewsScopes)
.WithParentActivityOrWindow(GetWindowHandle())
.ExecuteAsync();
同步等待身份验证任务的结果会遇到死锁。问题是继续。每个线程都在一个上下文中运行。在
ExecuteAsync
中,等待任务,当任务完成时,该方法在当前上下文中继续执行,在您的示例中,当前上下文就是UI上下文。由于该操作需要一段时间,因此将不完整的任务返回到ExecutedAsync
,并捕获UI上下文。现在,返回到方法的任务也不完整,通过task.Result
您可以在UI上下文中同步等待它完成。然后,当任务最终完成时,ExecuteAsync
方法无法在捕获的UI上下文上继续运行,因为等待任务的结果会阻止它
Stephen Cleary有一个关于async/await和您可能遇到的问题的非常全面的博客系列。他详细地描述了这个问题,你应该好好看看。引用他的话:
不要阻塞任务;一直使用异步
其他选项包括使用ConfigureAwait
,但再次引用他作为该主题专家的话:
使用ConfigureAwait(false)来避免死锁充其量只是一种攻击)
我需要同步使用它,但解决了它。谢谢
AuthenticationResult result = await publicClientApplication
.AcquireTokenInteractive(_ewsScopes)
.WithParentActivityOrWindow(GetWindowHandle())
.ExecuteAsync();