1

我有 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;
    }
}
4

2 回答 2

2

感谢 Nate Diamond,我找到了一种解决方法(或者也许这是唯一的解决方案)。诀窍是等待初始化并在主线程中连接(在Windows商店应用程序中,它不是ui线程,但不知何故它是主线程),然后创建线程并在其中等待GetAsync。为了清楚起见,我跳过了所有 try..catch..finally 和所有不必要的内容。现在它让绘制线程工作没有冻结。这里的代码:

private static LiveConnectSession session = null;
private static LiveAuthClient liveAuthClient = null;
private static LiveConnectClient liveConnectClient = null;

public static async Task AuthAsync()
{
    await AuthAsyncInternal();
    if (liveConnectClient != null)
    {
        await Task.Run(async () =>
            {
                LiveOperationResult liveOperationResult = 
                    await liveConnectClient.("me");
                dynamic meResult = liveOperationResult.Result;
                MyEngine.userID = meResult.id;
            });
    }
}

private static async Task AuthAsyncInternal()
{
    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);
    }
}

这是 Windows Phone 8 的变体:

private static async Task AuthAsyncInternal()
{
    Deployment.Current.Dispatcher.BeginInvoke(async delegate()
        {
            liveAuthClient = new LiveAuthClient("your client id here");
            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);
                await Task.Run(async () =>
                    {
                        LiveOperationResult liveOperationResult = 
                            await liveConnectClient.("me");
                        dynamic meResult = liveOperationResult.Result;
                        MyEngine.userID = meResult.id;
                    });
            }
        });
}
于 2014-03-13T20:03:51.473 回答
0

有点偏离主题(不是关于线程),但可能对某人有帮助。

我发现对 LiveAuthClient 的 LoginAsync() 的调用最多需要 12 秒,通常大约需要 7-8 秒(在 c# 和 XAML 中的 win 8.1 商店应用程序中)

例如

LiveAuthClient auth = new LiveAuthClient(_redirectDomain);
_loginResult = await auth.LoginAsync(new string[] { "wl.signin", "wl.basic", "wl.emails" });

发现一旦我关闭 Fiddler(一个 http 代理/检查器),它就会下降更合理的 ~2 秒

仍然非常缓慢和蹩脚(不知道为什么这么慢 - 注意:我认为从 5.5 升级到 5.6 会减慢速度)但显然要好得多。

可能会帮助某人。

于 2014-07-04T09:52:55.913 回答