0

OAuth2を使用してWindowsPhone7のGoogleAPIでいくつかの作業を行っています。

APIを呼び出す前に、アクセストークンを更新する必要があります(必要な場合)。

私が抱えている問題は、APIの呼び出しを続行する前に、トークンの更新が完了する非同期リクエストを待っていることです。

以下のコードで動作しますが、満足していません。whileループで変数を単純にポーリングするよりも良い代替手段を探しています。

    /// <summary>
    /// Calls the API.
    /// </summary>
    /// <param name="callback">The callback.</param>
    /// <param name="api">The API.</param>
    /// <param name="queryStrings">The query strings.</param>
    public static void CallApi(AsyncCallback callback, string api, Dictionary<string, string> queryStrings = null)
    {
        var uri = new Uri(string.Format("{0}{1}{2}", ApiBaseUrl, api, queryStrings.ToQueryString()));

        if (accessTokenExpires < DateTime.Now.AddSeconds(300))
        {
            RefreshAccessToken();
        }

        // Start new thread so we don't lock up the UI thread while waiting
        var thread = new Thread(
            () =>
                {
                    // Wait for the access token to be updated
                    while (accessTokenExpires < DateTime.Now.AddSeconds(300)) ;

                    var request = WebRequest.CreateHttp(uri);
                    request.Headers["Authorization"] = string.Format("OAuth {0}", accessToken);
                    request.BeginGetResponse(callback, request);
                });

        thread.Start();
    }

    /// <summary>
    /// Refresh the access token.
    /// </summary>
    private static void RefreshAccessToken()
    {
        if (Config.GoogleOAuthRefreshToken == string.Empty)
        {
            // TODO - Present the OAuth popup to the user
            return;
        }

        var uri = new Uri(GetTokenUrl);

        var request = WebRequest.CreateHttp(uri);
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";

        request.BeginGetRequestStream(RefreshToken_GetRequest, request);
    }
4

2 に答える 2

2

必要なものの始まりはあると思いますが、WebRequest の非同期の性質を最大限に活用する必要があります。これを行う方法の例を次に示します

public static void CallApi(AsyncCallback callback, string api, Dictionary<string, string> queryStrings = null)
{
    var uri = new Uri(string.Format("{0}{1}{2}", ApiBaseUrl, api, queryStrings.ToQueryString()));

    RefreshAccessToken(() =>
        {
            var request = WebRequest.CreateHttp(uri);
            request.Headers["Authorization"] = string.Format("OAuth {0}", accessToken);
            request.BeginGetResponse(callback, request);
        });
}

private static void RefreshAccessToken(Action callback)
{
    if(IsTokenExpired() == false)
    {
        if(callback != null) callback();
        return;
    }
    if (Config.GoogleOAuthRefreshToken == string.Empty)
    {
        // TODO - Present the OAuth popup to the user
        return;
    }

    var uri = new Uri(GetTokenUrl);

    var request = WebRequest.CreateHttp(uri);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    request.BeginGetRequestStream(asyncResult =>
    {
        // Do anything for POST
        request.BeginGetResponse(asyncResult2 =>
        {
            // Read stream, and process
            if(callback != null) callback();
        }, null);
    }, request);
}

private bool IsTokenExpired()
{
    return accessTokenExpires < DateTime.Now.AddSeconds(300);
}
于 2012-08-23T18:02:14.947 に答える
0

Async-CTPまたは VS 2012 を使用して、このロジックを Task.Delay 呼び出しに変換することを検討しましたか? おそらく、Web 要求コードにも役立つ可能性があります。

于 2012-08-23T16:52:18.373 に答える