为什么异步调用LiveConnectClient.GetAsync块执行线程?

时间:2014-03-10 15:26:17

标签: c# windows-store-apps async-await monogame live-connect-sdk

我有Windows Store MonoGame(基于Visual Studio 2012中的XAML MonoGame模板)app。 当我连接到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;
    }
}

2 个答案:

答案 0 :(得分: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;
                    });
            }
        });
}

答案 1 :(得分:0)

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

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

e.g。

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

发现一旦我关闭了Fiddler (一个http代理/检查员),这个掉线到了更合理~2秒

仍然很慢而且很蹩脚(不知道为什么它如此缓慢 - 注意:我认为从5.5升级到5.6会减慢它速度)但显然要好得多。

可以帮助别人。