为什么async调用LiveConnectClient.GetAsync块执行线程

本文关键字:执行 线程 GetAsync LiveConnectClient async 调用 为什么 | 更新日期: 2023-09-27 17:49:01

我有Windows Store MonoGame(基于Visual Studio 2012中的XAML MonoGame模板)应用程序。
当我连接到LiveConnect时,系统在后台做所有的事情,但是当我调用LiveConnectClient时。GetAsync获取用户信息有时(通常)会阻塞调用线程,即使它是使用await调用的。是否有任何方法使GetAsync调用真正异步?也许我应该创建一个新线程来调用它?

这是呼叫者代码。

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;
    }
}

为什么async调用LiveConnectClient.GetAsync块执行线程

感谢Nate Diamond,我找到了一个解决方案(或者可能是唯一的解决方案)。诀窍是在主线程中等待初始化和连接(在windows商店应用程序中,它不是ui线程,但不知何故它是主线程),然后创建线程并在其中等待GetAsync。为了清楚起见,我跳过了所有的try…catch…最后和所有不必要的东西。现在它让绘制线程工作无冻结。代码如下:

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;
                    });
            }
        });
}

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

我发现一个调用LiveAuthClient的LoginAsync()是采取高达12秒,通常约7-8秒(在win8.1商店应用c# &XAML)

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

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

这个仍然是相当缓慢和蹩脚的(不知道为什么它这么慢-注意:我认为从5.5升级到5.6减慢了),但显然好多了。

可能对某人有帮助。