将HttpWebRequest从Synchronous转换为异步代码

时间:2017-03-29 16:28:48

标签: c# asynchronous

我需要将此代码从同步转换为异步代码,但到目前为止的每次尝试都是令人沮丧的。有人会有解决方案吗?

 var http = (HttpWebRequest)WebRequest.Create(Connection.GetUri(path).Uri);
 http.Accept = "application/json";
 http.ContentType = "application/json";
 http.Method = "POST";

 var parsedContent = JsonConvert.SerializeObject(value);
 var encoding = new ASCIIEncoding();
 var bytes = encoding.GetBytes(parsedContent);

 var newStream = http.GetRequestStream();
 newStream.Write(bytes, 0, bytes.Length);
 newStream.Close();

 var response = http.GetResponse();

 var stream = response.GetResponseStream();

 var sr = new StreamReader(stream);

 return JsonConvert.DeserializeObject<TReturnType>(sr.ReadToEnd());

对于上下文,问题是我不能使用System.Net.Http程序集但需要Async支持 。 由于使用上述组件的残疾,上述代码已从以下移植。 Connection.Client是HttpClient类型。

var response = await Connection.Client.PostAsync(
   Connection.GetUri("/transaction/announce").Uri,
   new StringContent(JsonConvert.SerializeObject(Rpa).ToString(),
       Encoding.UTF8,
       "application/json"));

return JsonConvert.DeserializeObject<NemAnnounceResponse.Response>(
    await response.Content.ReadAsStringAsync());

1 个答案:

答案 0 :(得分:0)

HttpWebRequest不提供基于任务的现代异步方式来获取响应。但它允许您使用旧的APM模式进行异步调用。请参阅BeginGetResponse方法。

幸运的是,您可以使用Task.Factory.FromAsync之类的辅助方法轻松地将老式APM转换为基于任务的APM。最终你应该得到像这样的东西:

public static Task<WebResponse> GetResponseAsync()
{
    var http = (HttpWebRequest)WebRequest.Create(Connection.GetUri(path).Uri);
    http.Accept = "application/json";
    http.ContentType = "application/json";
    http.Method = "POST";

    var parsedContent = JsonConvert.SerializeObject(value);
    var encoding = new ASCIIEncoding();
    var bytes = encoding.GetBytes(parsedContent);

    var newStream = http.GetRequestStream();
    newStream.Write(bytes, 0, bytes.Length);
    newStream.Close();

    Task<WebResponse> task = Task.Factory.FromAsync(
        http.BeginGetResponse,
        asyncResult => http.EndGetResponse(asyncResult),
        (object)null);

    return task;
}

甚至可以使用等待var response = await GetResponseAsync();等来调用它,然后继续响应。