我試圖將一些數據發佈到Web服務並在控制檯應用程序中接收HttpClient的響應。如果我嘗試重用一個HttpClient實例,PostAsJsonAsync的第一個調用按預期工作,但第二個只是等待。如果我爲每個呼叫創建一個新的HttpClient,那麼一切都可以。第二次調用HttpClient的PostAsJsonAsync stucks
public class DirectHandler
{
HttpClient httpClient;
public string SendToPlayer(object message)
{
if (httpClient == null)
{
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("..url...");
}
HttpResponseMessage response = httpClient.PostAsJsonAsync("", message).Result; // Blocking call!
if (response.IsSuccessStatusCode)
{
var result = response.Content.ReadAsByteArrayAsync().Result;
return System.Text.Encoding.Default.GetString(result);
}
else
{
throw new HttpRequestException("Error code " + response.StatusCode + ", reason: " + response.ReasonPhrase);
}
}
}
使用這個類的代碼:
DirectHandler dh = new DirectHandler();
var resp = dh.SendToPlayer(myObj);
Console.WriteLine("Received: " + resp);
Thread.Sleep(500);
resp = dh.SendToPlayer(myObj);
Console.WriteLine("Received: " + resp);
「服務器」 是一個HttpListener:
public class HTTPServer
{
void StartListener()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("my prefix");
listener.Start();
listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);
}
private void OnRequestReceive(IAsyncResult result)
{
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
HttpListenerResponse response = context.Response;
HttpListenerRequest request = context.Request;
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding))
{
Console.WriteLine(reader.ReadToEnd());
}
string responseString = "{'a': \"b\"}";
byte[] buffer = Encoding.UTF8.GetBytes(responseString);
response.ContentLength64 = buffer.Length;
response.OutputStream.Write(buffer, 0, buffer.Length);
listener.BeginGetContext(new AsyncCallback(OnRequestReceive), listener);
}
}
我怎麼能重複使用的HttpClient?
更新: 我改變了。結果到異步/ AWAIT,現在SendToPlayer方法是這樣的:
public async Task<string> SendToPlayer(object message)
{
if (httpClient == null)
{
httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("..url...");
}
HttpResponseMessage response = await httpClient.PostAsJsonAsync("", message).ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsByteArrayAsync();
return System.Text.Encoding.Default.GetString(result);
}
else
{
throw new HttpRequestException("Error code " + response.StatusCode + ", reason: " + response.ReasonPhrase);
}
}
它仍然永遠PostAsJsonAsync時多次調用等待。
UPDATE2:
測試代碼,掛在第二SendToPlayer行:
public static void Main(string[] args)
{
Task.Run(async() =>
{
DirectHandler dh = new DirectHandler();
var resp = await dh.SendToPlayer(myObj);
Console.WriteLine("Received: " + str);
Thread.Sleep(500);
resp = await dh.SendToPlayer(myObj);
Console.WriteLine("Received: " + str);
}).Wait();
}
使用async/await時,不要等待使用.Result或.Wait()的異步方法時,請始終使用'await'。根據環境環境。結果和.Wait可能導致死鎖。 –
我重寫了我的代碼以使用await而不是.Result無處不在,但沒有任何更改。我也試過.PostAsJsonAsync(...)。ConfigureAwait(false),但第二次調用它仍然掛起。 – gberes
顯示你如何重寫代碼,以便我們看到你做了什麼。 – Nkosi