为什么异步调用LiveConnectClient.GetAsync块执行的线程? [英] why does async call LiveConnectClient.GetAsync block executing thread?

查看:272
本文介绍了为什么异步调用LiveConnectClient.GetAsync块执行的线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows商店MonoGame(基于在Visual Studio 2012 XAML MonoGame模板)应用程序。结果
当我连接到LiveConnect的,系统不会在后台所有的事情,但是当我打电话LiveConnectClient.GetAsync获得用户信息有时(通常)阻塞调用者线程,即使它使用的await被调用。
有没有什么办法让GetAsync电话真的异步?也许我应该创建一个新的线程来调用它呢?

下面是主叫code。这就是所谓的内部MonoGame画线(无法访问MonoGame主UI线程)。

 私有静态LiveConnectSession会话= NULL;
私有静态LiveAuthClient liveAuthClient = NULL;
私有静态LiveConnectClient liveConnectClient = NULL;公共静态异步任务AuthAsync()
{
    liveAuthClient =新LiveAuthClient();
    LiveLoginResult liveLoginResult =等待liveAuthClient.InitializeAsync();
    liveLoginResult =等待liveAuthClient.LoginAsync(新名单<串GT; {wl.signin});
    如果(liveLoginResult.Status == LiveConnectSessionStatus.Connected)
    {
        会话= liveLoginResult.Session;
        liveConnectClient =新LiveConnectClient(会话);
        LiveOperationResult liveOperationResult =等待liveConnectClient.GetAsync(我);
        动态meResult = liveOperationResult.Result;
        MyEngine.userID = meResult.id;
    }
}


解决方案

由于内特钻石,我找到了一个解决方法(或者也许是唯一的解决办法)。关键是要等待intialization,并在主线程连接(在Windows商店应用它不是UI线程,但不知何故,这是主要的一个),然后创建线程,并在它等待GetAsync。为了清楚起见,我跳过所有try..catch..finally代码和一切不必要的。现在,让我们画线工作的w / o冻结。这里的code:

 私有静态LiveConnectSession会话= NULL;
私有静态LiveAuthClient liveAuthClient = NULL;
私有静态LiveConnectClient liveConnectClient = NULL;公共静态异步任务AuthAsync()
{
    等待AuthAsyncInternal();
    如果(liveConnectClient!= NULL)
    {
        等待Task.Run(异步()=>
            {
                LiveOperationResult liveOperationResult =
                    等待liveConnectClient(我)。
                动态meResult = liveOperationResult.Result;
                MyEngine.userID = meResult.id;
            });
    }
}私有静态异步任务AuthAsyncInternal()
{
    liveAuthClient =新LiveAuthClient();
    LiveLoginResult liveLoginResult =等待liveAuthClient.InitializeAsync();
    liveLoginResult =等待liveAuthClient.LoginAsync(新名单<串GT; {wl.signin});
    如果(liveLoginResult.Status == LiveConnectSessionStatus.Connected)
    {
        会话= liveLoginResult.Session;
        liveConnectClient =新LiveConnectClient(会话);
    }
}

和这里的变种的Windows Phone 8:

 私有静态异步任务AuthAsyncInternal()
{
    Deployment.Current.Dispatcher.BeginInvoke(异步委托()
        {
            liveAuthClient =新LiveAuthClient(这里的客户端ID);
            LiveLoginResult liveLoginResult =等待liveAuthClient.InitializeAsync();
            liveLoginResult =等待liveAuthClient.LoginAsync(新名单<串GT; {wl.signin});
            如果(liveLoginResult.Status == LiveConnectSessionStatus.Connected)
            {
                会话= liveLoginResult.Session;
                liveConnectClient =新LiveConnectClient(会话);
                等待Task.Run(异步()=>
                    {
                        LiveOperationResult liveOperationResult =
                            等待liveConnectClient(我)。
                        动态meResult = liveOperationResult.Result;
                        MyEngine.userID = meResult.id;
                    });
            }
        });
}

I have Windows Store MonoGame (based on XAML MonoGame template in Visual Studio 2012) app.
When I connect to LiveConnect, system does all things in background, but when I call LiveConnectClient.GetAsync to get user info it sometimes (and usually) blocks the caller thread, even though it is called using await. Is there any way to make GetAsync call really async? Maybe I should create a new thread to call it?

Here's the caller code. It is called inside MonoGame draw thread (can't access main UI thread in MonoGame).

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

解决方案

Thanks to Nate Diamond, I've found a workaround (or maybe it's the only solution). The trick is to await intialization and connect in main thread (in windows store app it's not the ui thread, but somehow it's the main one), then create thread and await GetAsync in it. For the sake of clarity I've skipped all try..catch..finally and everything unnecessary. Now it let draw thread work w/o freezes. Here' the code:

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

And here's variant for 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;
                    });
            }
        });
}

这篇关于为什么异步调用LiveConnectClient.GetAsync块执行的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆