3

私は C# のタスクを初めて使用します。仮想マシンを起動するために azure にアーム テンプレートを展開する例に従っています: https://azure.microsoft.com/en-us/documentation/articles/arm-template-deployment/

ここで説明する最初の操作の 1 つは、Active Directory を呼び出して認証トークンを取得することです。リンクで指定されたコードは、非推奨と思われる AcquireToken API を使用しており、現在、AcquireTokenAsync しか見つかりませんでした。そこで、タスクを作成して完了するまで待つようにコードを変更しました。

private static string GetAuthorizationHeader()
{
    ClientCredential cc = new ClientCredential("{application-id}", "{password}");
    var context = new AuthenticationContext("https://login.windows.net/{tenant-id}");

    Task<AuthenticationResult> acquireTokenTask = context.AcquireTokenAsync("https://management.azure.com/", cc);
    Task.WhenAll(acquireTokenTask);
    AuthenticationResult result = acquireTokenTask.Result;
    if (result == null)
    {
      throw new InvalidOperationException("Failed to obtain the JWT token");
    }

    string token = result.AccessToken;

    return token;
}

acquireTokenTask のステータスが "RanToCompletion" になるまで、その Task.WhenAll がブロックされることを期待していました。ただし、ステータスが「WaitingForActivation」であっても、WhenAll はブロックされておらず、コントロールは次のステートメントに進み、acquireTokenTask.Result を取得しようとします。これにより、リクエストの送信中にエラーが発生したという例外の詳細を示す例外が発生します。

質問:
1. ステータスが「RanToCompletion」に変化しないというリクエストの送信にエラーがありますか? 10回の実行のうち2〜3回が「RanToCompletion」ステータスで成功し、結果を取得できるため、これは当てはまらないと思います。
2. Task.WhenAll は、実行が完了するまでスレッドをブロックすると思いました。これは真実ではありませんか?true の場合、コントロールが次のステートメントにどのように渡されているのか疑問に思っています。
3. この問題を解決し、結果が抽出されるまでにすべての実行で成功した結果を得るにはどうすればよいですか?

4

1 に答える 1

3

Task.WhenAll は、実行が完了するまでスレッドをブロックすると思いました。これは真実ではありませんか?

Task.WhenAll必要な awaitable を返しますawait。現在、あなたはあなたを渡しますTaskが、あなたがそれをブロックするまでコードを実行し続けますTask.Result. ただし、それはここではまったく必要ありません。WhenAll非同期に待機する必要があるタスクが複数ある場合に使用します。ここでは、単一の await を単に待つことができますTask:

private static async Task<string> GetAuthorizationHeaderAsync()
{
    ClientCredential cc = new ClientCredential("{application-id}", "{password}");
    var context = new AuthenticationContext("https://login.windows.net/{tenant-id}");

    AuthenticationResult result = await context.AcquireTokenAsync(
                                            "https://management.azure.com/", cc);
    if (result == null)
    {
        throw new InvalidOperationException("Failed to obtain the JWT token");
    }

    string token = result.AccessToken;
    return token;
}
于 2015-08-27T05:10:07.510 に答える