C# 为什么要使用 HttpClient 进行同步连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14435520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why use HttpClient for Synchronous Connection
提问by Ketchup
I am building a class library to interact with an API. I need to call the API and process the XML response. I can see the benefits of using HttpClient
for Asynchronous connectivity, but what I am doing is purely synchronous, so I cannot see any significant benefit over using HttpWebRequest
.
我正在构建一个类库来与 API 交互。我需要调用 API 并处理 XML 响应。我可以看到使用HttpClient
异步连接的好处,但我所做的完全是同步的,所以我看不到使用HttpWebRequest
.
If anyone can shed any light I would greatly appreciate it. I am not one for using new technology for the sake of it.
如果有人能阐明任何观点,我将不胜感激。我不是为了它而使用新技术的人。
采纳答案by Darin Dimitrov
but what i am doing is purely synchronous
但我正在做的纯粹是同步的
You could use HttpClient
for synchronous requests just fine:
您可以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);
}
}
As far as why you should use HttpClient
over WebRequest
is concerned, well, HttpClient
is the new kid on the block and could contain improvements over the old client.
至于为什么你应该使用HttpClient
over WebRequest
,嗯,HttpClient
是块上的新孩子,可能包含对旧客户端的改进。
回答by Josh Smeaton
If you're building a class library, then perhaps the users of your library would like to use your library asynchronously. I think that's the biggest reason right there.
如果您正在构建一个类库,那么您库的用户可能希望异步使用您的库。我认为这是最大的原因。
You also don't know how your library is going to be used. Perhaps the users will be processing lots and lots of requests, and doing so asynchronously will help it perform faster and more efficient.
您也不知道将如何使用您的库。也许用户将处理大量的请求,异步处理将有助于它执行得更快、更高效。
If you can do so simply, try not to put the burden on the users of your library trying to make the flow asynchronous when you can take care of it for them.
如果您可以简单地做到这一点,请尽量不要在您可以为他们处理流程的情况下,将试图使流程异步化的图书馆用户的负担加重。
The only reason I wouldn't use the async version is if I were trying to support an older version of .NET that does not already have built in async support.
我不使用异步版本的唯一原因是,如果我试图支持尚未内置异步支持的旧版本 .NET。
回答by trev
I'd re-iterate Donny V. answer and Josh's
我会重申 Donny V. 的回答和 Josh 的回答
"The only reason I wouldn't use the async version is if I were trying to support an older version of .NET that does not already have built in async support."
“我不使用异步版本的唯一原因是,如果我试图支持尚未内置异步支持的旧版本 .NET。”
(and upvote if I had the reputation.)
(如果我有声望,请点赞。)
I can't remember the last time if ever, I was grateful of the fact HttpWebRequest threw exceptions for status codes >= 400. To get around these issues you need to catch the exceptions immediately, and map them to some non-exception response mechanisms in your code...boring, tedious and error prone in itself. Whether it be communicating with a database, or implementing a bespoke web proxy, its 'nearly' always desirable that the Http driver just tell your application code what was returned, and leave it up to you to decide how to behave.
我不记得上次是什么时候了,我很感激 HttpWebRequest 抛出状态代码 >= 400 的异常。要解决这些问题,您需要立即捕获异常,并将它们映射到一些非异常响应机制在您的代码中...本身就很乏味、乏味且容易出错。无论是与数据库通信,还是实现定制的 Web 代理,“几乎”总是希望 Http 驱动程序只告诉您的应用程序代码返回的内容,并由您决定如何操作。
Hence HttpClient is preferable.
因此 HttpClient 更可取。
回答by Jonathan Alfaro
In my case the accepted answer did not work. I was calling the API from an MVC application which had no async actions.
在我的情况下,接受的答案不起作用。我从一个没有异步操作的 MVC 应用程序调用 API。
This is how I managed to make it work:
这就是我设法让它工作的方式:
private static readonly TaskFactory _myTaskFactory = new TaskFactory(CancellationToken.None, TaskCreationOptions.None, TaskContinuationOptions.None, TaskScheduler.Default);
public static T RunSync<T>(Func<Task<T>> func)
{
CultureInfo cultureUi = CultureInfo.CurrentUICulture;
CultureInfo culture = CultureInfo.CurrentCulture;
return _myTaskFactory.StartNew<Task<T>>(delegate
{
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = cultureUi;
return func();
}).Unwrap<T>().GetAwaiter().GetResult();
}
Then I called it like this:
然后我这样称呼它:
Helper.RunSync(new Func<Task<ReturnTypeGoesHere>>(async () => await AsyncCallGoesHere(myparameter)));
回答by Lean Bonaventura
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());
if you use that class pass your async method as parameter you can call the async methods from sync methods in a safe way.
如果您使用该类将异步方法作为参数传递,则可以安全地从同步方法中调用异步方法。
it's explained here : https://cpratt.co/async-tips-tricks/
它在这里解释:https: //cpratt.co/async-tips-tricks/
回答by Bizniztime
All answers seem to focus on using HttpClient
synchronously instead of giving actual answer to question.
所有的答案似乎都集中在HttpClient
同步使用上,而不是给出问题的实际答案。
HttpClient
is more than a simple request/response handler so it can deal with some peculiarities of different networks. Namely in my case working with NTLM proxy which requires negotiation, sending multiple request/responses with tokens and credentials between client and proxy server to authenticate. HttpClient
(using HttpClientHandler
) seems to have built-in mechanism which handles that returns resources beyond proxy with one method call.
HttpClient
不仅仅是一个简单的请求/响应处理程序,因此它可以处理不同网络的一些特性。即在我的情况下,使用需要协商的 NTLM 代理,在客户端和代理服务器之间发送多个带有令牌和凭据的请求/响应以进行身份验证。HttpClient
(使用HttpClientHandler
)似乎具有内置机制,可以处理通过一个方法调用返回代理之外的资源。