我正在构建一个与API交互的类库。我需要调用API并处理XML响应。我可以看到使用HttpClient进行异步连接的好处,但是我所做的是纯同步的,所以我看不出使用HttpWebRequest有什么显著的好处。
如果有人能说点什么,我将非常感激。我不是那种为了使用新技术而使用新技术的人。
我正在构建一个与API交互的类库。我需要调用API并处理XML响应。我可以看到使用HttpClient进行异步连接的好处,但是我所做的是纯同步的,所以我看不出使用HttpWebRequest有什么显著的好处。
如果有人能说点什么,我将非常感激。我不是那种为了使用新技术而使用新技术的人。
当前回答
但是我所做的是完全同步的
你可以使用HttpClient进行同步请求:
using (var client = new HttpClient())
{
var response = client.GetAsync("http://google.com").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
Console.WriteLine(responseString);
}
}
至于为什么你应该在WebRequest上使用HttpClient,好吧,HttpClient是块上的新孩子,可以包含对旧客户端的改进。
其他回答
对于现在遇到这个问题的人来说,. net 5.0已经向HttpClient添加了一个同步发送方法。https://github.com/dotnet/runtime/pull/34948
原因在这里有详细的讨论:https://github.com/dotnet/runtime/issues/32125
因此,您可以使用这个而不是SendAsync。例如
public string GetValue()
{
var client = new HttpClient();
var webRequest = new HttpRequestMessage(HttpMethod.Post, "http://your-api.com")
{
Content = new StringContent("{ 'some': 'value' }", Encoding.UTF8, "application/json")
};
var response = client.Send(webRequest);
using var reader = new StreamReader(response.Content.ReadAsStream());
return reader.ReadToEnd();
}
这段代码只是一个简化的示例,还不能用于生产。
但是我所做的是完全同步的
你可以使用HttpClient进行同步请求:
using (var client = new HttpClient())
{
var response = client.GetAsync("http://google.com").Result;
if (response.IsSuccessStatusCode)
{
var responseContent = response.Content;
// by calling .Result you are synchronously reading the result
string responseString = responseContent.ReadAsStringAsync().Result;
Console.WriteLine(responseString);
}
}
至于为什么你应该在WebRequest上使用HttpClient,好吧,HttpClient是块上的新孩子,可以包含对旧客户端的改进。
在当今时代,对这个问题的最简短的回答是非常直接的:字面上说,除了HttpClient之外的所有先前的。net选项现在都已弃用/过时了。
如果您正在构建一个类库,那么您的库的用户可能希望异步使用您的库。我认为这是最大的原因。
您也不知道您的库将如何使用。也许用户将处理大量的请求,异步处理将帮助它更快更有效地执行。
如果您可以简单地做到这一点,那么当您可以为库的用户处理流时,尽量不要让他们承担试图使流异步化的负担。
我不使用异步版本的唯一原因是,如果我试图支持一个尚未内置异步支持的旧版本的。net。
public static class AsyncHelper
{
private static readonly TaskFactory _taskFactory = new
TaskFactory(CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default);
public static TResult RunSync<TResult>(Func<Task<TResult>> func)
=> _taskFactory
.StartNew(func)
.Unwrap()
.GetAwaiter()
.GetResult();
public static void RunSync(Func<Task> func)
=> _taskFactory
.StartNew(func)
.Unwrap()
.GetAwaiter()
.GetResult();
}
Then
AsyncHelper.RunSync(() => DoAsyncStuff());
如果你使用这个类来传递你的async方法作为参数,你可以以一种安全的方式从sync方法调用async方法。
解释如下: https://cpratt.co/async-tips-tricks/