Ket*_*hup 173 c# asp.net dotnet-httpclient
我正在构建一个类API来与API进行交互.我需要调用API并处理XML响应.我可以看到HttpClient
用于异步连接的好处,但我正在做的是纯粹的同步,所以我看不到使用它的任何重大好处HttpWebRequest
.
如果有人可以放弃任何光线,我将非常感激.我不是为了它而使用新技术的人.
Dar*_*rov 349
但我正在做的是纯粹的同步
您可以使用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);
}
}
Run Code Online (Sandbox Code Playgroud)
至于为何你应该使用HttpClient而不是WebRequest,那么,HttpClient是块中的新手,可能包含对旧客户端的改进.
小智 26
我会重复Donny V.回答和Josh的回答
"我不使用异步版本的唯一原因是,如果我试图支持尚未内置异步支持的旧版.NET."
(并且如果我有声誉的话,请进行投票.)
我不记得最后一次,如果有的话,我很感激HttpWebRequest为状态代码> = 400抛出异常这一事实.要解决这些问题,你需要立即捕获异常,并将它们映射到一些非异常响应机制在你的代码中......无聊,乏味且容易出错.无论是与数据库进行通信,还是实现定制的Web代理,它"几乎"总是希望Http驱动程序只是告诉您的应用程序代码返回的内容,并由您决定如何操作.
因此HttpClient是优选的.
Lea*_*ura 10
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();
}
Run Code Online (Sandbox Code Playgroud)
然后
AsyncHelper.RunSync(() => DoAsyncStuff());
Run Code Online (Sandbox Code Playgroud)
如果您使用该类将异步方法作为参数传递,则可以安全地从同步方法中调用异步方法。
它在这里解释:https : //cpratt.co/async-tips-tricks/
ale*_*exs 10
对于现在遇到此问题的任何人,.NET 5.0 已将同步Send
方法添加到HttpClient
. https://github.com/dotnet/runtime/pull/34948
优点也是为什么在这里详细讨论 - https://github.com/dotnet/runtime/issues/32125
因此,您可以使用 this 而不是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();
}
Run Code Online (Sandbox Code Playgroud)
这段代码只是一个简化的例子,它不是生产就绪的。
如果您正在构建类库,那么您的库的用户可能希望异步使用您的库.我认为那是最大的原因.
您也不知道您的图书馆将如何使用.也许用户将处理大量的请求,并且异步执行这些操作将有助于它更快,更高效地执行.
如果你可以这样做,尽量不要让你的库的用户负担,试图让流程异步,你可以为它们处理它.
我不使用异步版本的唯一原因是,如果我试图支持尚未内置异步支持的旧版.NET.
在我的情况下,接受的答案不起作用.我从一个没有异步操作的MVC应用程序调用API.
这就是我设法让它工作的方式:
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();
}
Run Code Online (Sandbox Code Playgroud)
然后我这样打电话:
Helper.RunSync(new Func<Task<ReturnTypeGoesHere>>(async () => await AsyncCallGoesHere(myparameter)));
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
140484 次 |
最近记录: |