asp.net 为什么使用HttpClient进行同步连接

mzsu5hc0  于 2022-11-19  发布在  .NET
关注(0)|答案(7)|浏览(168)

我正在构建一个类库来与API交互。我需要调用API并处理XML响应。我可以看到使用HttpClient进行异步连接的好处,但我所做的是纯粹的同步,所以我看不到使用HttpWebRequest有任何明显的好处。
如果有人能提供任何启示,我将不胜感激。我不是一个为了新技术而使用新技术的人。

ffdz8vbo

ffdz8vbo1#

但我现在做的是完全同步的
您可以将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);
    }
}

至于为什么应该使用HttpClient而不是WebRequest,那么,HttpClient是块上的新孩子,可能包含对旧客户机的改进。

mkh04yzy

mkh04yzy2#

我会重复唐尼的回答和乔什的
“我不使用异步版本的唯一原因是,如果我试图支持尚未内置异步支持的.NET旧版本。”
(and如果我有这样的名声,我会投赞成票。)
我已经记不清上一次HttpWebRequest抛出状态代码〉= 400的异常是什么时候了。为了解决这些问题,您需要立即捕获异常,并将它们Map到代码中的一些非异常响应机制......这本身就很无聊、乏味而且容易出错。无论是与数据库通信,还是实现定制的Web代理,"几乎“总是希望Http驱动程序只告诉您的应用程序代码返回了什么,并让您决定如何操作。
因此,HttpClient是首选。

xtupzzrd

xtupzzrd3#

对于现在遇到这种情况的任何人,.NET 5.0为HttpClient添加了一个同步Send方法。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();
}

这段代码只是一个简化的示例-它还没有准备好投入生产。

r7s23pms

r7s23pms4#

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();
}

然后

AsyncHelper.RunSync(() => DoAsyncStuff());

如果使用类将异步方法作为参数传递,则可以安全地从同步方法调用异步方法。
这里有解释:https://cpratt.co/async-tips-tricks/

66bbxpm5

66bbxpm55#

如果你正在构建一个类库,那么你的类库的用户可能希望异步地使用你的类库,我认为这就是最大的原因。
你也不知道你的库将如何被使用,也许用户将处理很多很多的请求,异步地这样做将有助于它更快更有效地执行。
如果您可以简单地做到这一点,请尽量不要让库的用户在您可以为他们处理异步流的情况下尝试使流异步。
我不使用异步版本的唯一原因是,如果我试图支持一个没有内置异步支持的旧版本的.NET。

2eafrhcq

2eafrhcq6#

在我的例子中,接受的答案不起作用。我是从一个没有异步操作的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();
    }

后来我这样称呼它:

Helper.RunSync(new Func<Task<ReturnTypeGoesHere>>(async () => await AsyncCallGoesHere(myparameter)));
zi8p0yeb

zi8p0yeb7#

在当前时代,这个问题的最短答案相当直截了当:除HttpClient外,所有其他以前的.NET选项现在都已弃用/过时。

相关问题