1

HttpClientクラスと非同期呼び出しの呼び出しで問題が発生しています。page_loadから関数List()を呼び出します。呼び出しは、HttpResponseMessage response = await client.GetAsync(str);という行から返されます。そしてそれを終えるために二度と戻ってこない。

自分がどんな間違いをしているのかわかりません。以下は私のコードです:

        protected void Page_Load(object sender, EventArgs e)
        {
            Task<string> s= List(product); 
        }

        protected async Task<string> List(string ProductType)
        {
            string str = "http://xx.xx.com/wiki/api.php";


            using (HttpClient client = new HttpClient())
            {
                client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", "username", "password"))));
                HttpResponseMessage response = await client.GetAsync(str);

                response.EnsureSuccessStatusCode();

                string content = await response.Content.ReadAsStringAsync();
            }
            return content;
         }

次の行は実行されません。

response.EnsureSuccessStatusCode();
string content = await response.Content.ReadAsStringAsync();

助けてください。前もって感謝します。

4

1 に答える 1

1

のタスクに何が起こるかを示すことはありませんPage_Loadが、あなたの症状とそうでPage_Loadはないという事実を考えると、あなたはそれをing する代わりにorをasync呼び出しているに違いありません。ResultWaitawait

それを行うと、デッドロックが発生します。私のブログへのリンクで詳しく説明されていますが、要点はawait、現在の「コンテキスト」をキャプチャして復元することです。ASP.NET では、これは要求コンテキストであり、要求コンテキストでは一度に 1 つのスレッドしか実行できません。Resultそのため、(リクエスト コンテキスト内で) orを呼び出すとWait、そのリクエスト コンテキスト内のスレッドがTask<string>完了するまでブロックされます。一方、HttpClientは応答を受け取ると、 の後で再開を試みawait client.GetAsync(str)ます。ただし、リクエスト コンテキストでは一度に 1 つのスレッドしか許可されず、そのスレッドは がTask完了するのを待ってブロックされます。Listコンテキストがビジーであるため完了できないため、デッドロックが発生しています。

デッドロックを防ぐには、次の 2 つのベスト プラクティスに従ってください (最近の MSDN 記事から)

  1. asyncずっと使ってください。つまり、またはawaitの代わりに使用します。ResultWait
  2. ConfigureContext(false)「ライブラリ」コードで使用します。つまり、すべてawaitの入力Listは実際にはawait ... .ConfigureAwait(false);
于 2013-03-08T18:56:52.473 に答える