[英]Login without redirecting (or why LoginAsync() throws System.UnauthorizedAccessException)
我正在使用Windows Phone 8的Facebook.Client,以便處理游戲中通過Facebook進行的用戶登錄。
我正在使用Facebook.Client.FacebookSessionClient.LoginWithApp()
實現Facebook登錄功能,但是,這始終會導致重定向到我的應用程序頁面之一。 我使用MonoGame / XNA制作游戲,所以我的應用程序僅包含游戲頁面,游戲的每個部分都被繪制到其中。 重定向到它時,我失去了游戲的“進度”(因為重定向,游戲在主菜單中再次重新啟動)。
這種行為使我嘗試使用Facebook.Client.FacebookSessionClient.LoginAsync()
(我仍然不知道它的作用,因為我在某處找不到它,但是如果不引起重定向,那就是我所需要的) 。
我目前正在嘗試使用LoginAsync()
處理登錄,但是會LoginAsync()
此異常:
System.UnauthorizedAccessException:無效的跨線程訪問。
這是我正在使用的代碼(請注意,try-catch語句用於捕獲確切的異常,否則,我只會得到System.AggregateException
):
FacebookSessionClient fb = new FacebookSessionClient(AppId);
Task<FacebookSession> fbst = null;
FacebookSession fbs = null;
try
{
fbst = fb.LoginAsync("basic_info");
fbs = fbst.Result;
}
catch (AggregateException e)
{
Debug.WriteLine(e.ToString());
Debug.WriteLine(e.Message);
}
是什么導致未授權訪問異常? 另外,如果可以使用LoginWithApp()而不進行重定向(或其他任何形式的無需重定向的登錄),也可以做到這一點。
我設法找到此問題的解決方案。 之所以發生這種情況,是因為顯然在使用MonoGame時無法訪問Application.Current.RootVisual
,從而引發此異常。
如Windows 8和Windows Phone 8游戲開發一書的第438頁所述:
Windows Phone應用程序無法從游戲類代碼中與XAML控件進行交互,因為游戲代碼在不允許訪問UI組件的不同線程中運行。 為了解決這個問題,Dispatcher對象用於將更新排隊,以供UI線程處理。
在Facebook.Client的代碼(在其GitHub repo中可用)中, PhoneWebAuthentication.cs
中有一行可以執行以下操作:
PhoneApplicationFrame rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
這是導致異常並破壞LoginAsync()
行為的LoginAsync()
。
我已經在他們的GitHub頁面上打開了一個問題 。
現在,如果您希望LoginAsync()
使用MonoGame在WP8中工作(它不會導致重定向,因此正是我想要的!),則需要從以下位置下載Facebook.Windows Phone 8的源代碼上面提到的GitHub存儲庫,並將其鏈接到您的項目中。 之后,使AuthenticateAsync()
函數如下所示:
public static Task<WebAuthenticationResult> AuthenticateAsync(WebAuthenticationOptions options, Uri startUri, Uri endUri)
{
if (options != WebAuthenticationOptions.None)
{
throw new NotImplementedException("This method does not support authentication options other than 'None'.");
}
WebAuthenticationBroker.StartUri = startUri;
WebAuthenticationBroker.EndUri = endUri;
WebAuthenticationBroker.AuthenticationInProgress = true;
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
(Application.Current.RootVisual as PhoneApplicationFrame).Navigate(new Uri("/Facebook.Client;component/loginpage.xaml", UriKind.Relative));
});
Task<WebAuthenticationResult> task = Task<WebAuthenticationResult>.Factory.StartNew(() =>
{
authenticateFinishedEvent.WaitOne();
return new WebAuthenticationResult(responseData, responseStatus, responseErrorDetail);
});
return task;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.