4

私は WCF クライアント アプリに取り組んでおり、await/async パターンで問題に直面しています。次の行のようです: await client.LongOperationAsync(); 常にブロックします。私が理解しているように、スレッドは終了して Main() メソッドに進み、非同期メソッドが完了すると戻るはずでした。おそらく私は間違っています。

以下のコードの出力は (常に) です。

Test() 開始
Test() エラー
*
*
*
...

Test() メソッドは、コンテキストがメインに戻る前に常に完了します。どんな考えでも大歓迎です。

static void Main(string[] args)
{
    Program p = new Program();
    p.Test();
    while (true)
    {
        Console.WriteLine("*");
        Thread.Sleep(500);
    }       
}
private async Task Test()
{
    Console.WriteLine("Test() started");
    try
    {
        MySoapClient client = new MySoapClient(
            new BasicHttpBinding(new BasicHttpSecurityMode()),
            new EndpointAddress("http://badaddress"));
        await client.LongOperationAsync();
        Console.WriteLine("Test() success");
    }
    catch (Exception)
    {
        Console.WriteLine("Test() error");
        return;
    }
    Console.WriteLine("Test() end successfully");
}

4

1 に答える 1

4

非同期メソッドは、最初のawait;まで同期的に実行されます。メソッドが最初の await の前にブロッキング操作を実行するLongOperationAsyncと、呼び出し元のメソッドもブロックされます。それがあなたの場合に起こっていると思います。

これはおそらく、WebRequest.BeginGetResponseが一部の作業を同期的に実行するためです。この質問に対する Stephen Toub の回答を参照してください。

Async CTP の GetRequestStreamAsync と GetResponseAsync は、.NET 4 の既存の HttpWebRequest.BeginGetRequestStream と BeginGetResponse の単純なラッパーです。これらの Begin* メソッドには、送信前に行う多くのセットアップ作業 (プロキシ、DNS、接続プーリングなど) があります。残念ながら、今日ではすべての作業が Begin* 呼び出しの一部として同期的に行われます。

この場合は、不適切なドメイン名を指定したため、DNS 解決が失敗するまでに時間がかかると思われます。

于 2013-11-09T02:07:11.267 に答える