【发布时间】:2014-04-13 19:08:54
【问题描述】:
我有 Windows Store MonoGame(基于 Visual Studio 2012 中的 XAML MonoGame 模板)应用程序。
当我连接到 LiveConnect 时,系统会在后台执行所有操作,但是当我调用 LiveConnectClient.GetAsync 来获取用户信息时,它有时(并且通常)会阻塞调用者线程,即使它是使用 await 调用的。
有没有办法让 GetAsync 调用真正异步?也许我应该创建一个新线程来调用它?
这是调用者代码。它在 MonoGame 绘制线程中调用(在 MonoGame 中无法访问主 UI 线程)。
private static LiveConnectSession session = null;
private static LiveAuthClient liveAuthClient = null;
private static LiveConnectClient liveConnectClient = null;
public static async Task AuthAsync()
{
liveAuthClient = new LiveAuthClient();
LiveLoginResult liveLoginResult = await liveAuthClient.InitializeAsync();
liveLoginResult = await liveAuthClient.LoginAsync(new List<string> { "wl.signin" });
if (liveLoginResult.Status == LiveConnectSessionStatus.Connected)
{
session = liveLoginResult.Session;
liveConnectClient = new LiveConnectClient(session);
LiveOperationResult liveOperationResult = await liveConnectClient.GetAsync("me");
dynamic meResult = liveOperationResult.Result;
MyEngine.userID = meResult.id;
}
}
【问题讨论】:
-
你必须使用调用
AuthAsync的方法。如果你打电话给AuthAsync.Wait(),就可以了。 -
我在没有 Wait() 或 await 的情况下调用它(我知道我可以丢失异常,但在这种情况下不在乎)。所以我只是开火并继续线程执行。我的堆栈(非主线程):Monogame 的 void Game.Update-> void MyEngine.Update -> async void CurrentGameLevel.Update-> async Task AuthAsync。如果我评论“等待 liveConnectClient.GetAsync” - 一切顺利,否则游戏停止长达 10 秒 - 就像我使用同步调用一样。
-
根据this,您可能想尝试将其包装在
Task.Run中。我认为他在那里所做的基本上是将AuthAsync变成async void方法,或者只是强行将其移动到另一个线程。另一种选择是做类似的事情,但使用TaskCompletionSource在AuthAsync中返回Task,并让被调用的async方法设置Task的结果。 -
已尝试 Task.Run,但看起来 LiveConnect 无法登录此类 bg 线程: throws InnerException {"Unsupported. (Exception from HRESULT: 0x80070032)"} System.Exception。在 WP8 中,我使用 Deployment.Current.Dispatcher.BeginInvoke 在主线程中启动类似的 LiveConnect 代码,并且没有选项:只有主线程。尽管有所有这些等待,但同样的冻结。
-
我想我知道发生了什么。我认为它正在检查用户是否使用 Microsoft 帐户登录,因为如果不是,则需要抛出一个登录对话框。这可能就是它需要 UI 线程的原因。
标签: c# windows-store-apps async-await monogame live-connect-sdk