最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

ASP.NET Core使用IHttpClientFactory發(fā)出HTTP請(qǐng)求

 更新時(shí)間:2022年04月06日 15:08:54   作者:暗斷腸  
這篇文章介紹了ASP.NET Core使用IHttpClientFactory發(fā)出HTTP請(qǐng)求的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

1.HttpClient類使用存在的問(wèn)題

HttpClient類的使用所存在的問(wèn)題,百度搜索的文章一大堆,好多都是單純文字描述,讓人感覺(jué)不太好理解,為了更好理解HttpClient使用存在的問(wèn)題,下面讓我們通過(guò)代碼跟示例來(lái)描述。

using(var client = new HttpClient())

傳統(tǒng)關(guān)閉連接方法如上述代碼所示,但當(dāng)使用using語(yǔ)句釋放HttpClient對(duì)象的時(shí)候,套接字(socket)也不會(huì)立即釋放,下面我們通過(guò)請(qǐng)求aspnetmonsters站點(diǎn)的示例來(lái)驗(yàn)證下:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Starting connections");
        var g = GetAsync();
        g.Wait();
        Console.WriteLine("Connections done");
        Console.ReadKey();
    }
    static async Task GetAsync()
    {
        for (int i = 0; i < 5; i++)
        {
            using (var client = new HttpClient())
            {
                var result = await client.GetAsync("http://aspnetmonsters.com/");
                Console.WriteLine(result.StatusCode);
            }
        }
    }
}

輸出結(jié)果:

控制臺(tái)打印出五條請(qǐng)求站點(diǎn)返回狀態(tài)的信息,下面我們通過(guò)netstat工具打印出五個(gè)請(qǐng)求連接套接字狀態(tài):

應(yīng)用程序已經(jīng)運(yùn)行結(jié)束了(結(jié)束連接),但是打印結(jié)果顯示連接狀態(tài)仍然是TIME_WAIT,也就是說(shuō)在此狀態(tài)期間仍然在觀察是否有數(shù)據(jù)包進(jìn)入連接(如果連接等待中有任何數(shù)據(jù)包仍然會(huì)通過(guò)),因?yàn)樗鼈兛赡茉谀硞€(gè)地方被網(wǎng)絡(luò)延遲。

Windows將在此狀態(tài)下保持連接240秒(由其設(shè)置[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\TcpTimedWaitDelay])。Windows可以快速打開新套接字的速度有限,因此如果您耗盡連接池,那么您可能會(huì)看到如下錯(cuò)誤:

而怎么做才可以減少套接字的浪費(fèi)呢?我們?cè)谏鲜龃a中把每次循環(huán)中創(chuàng)建的HttpClient對(duì)象拉到Main外定義為一個(gè)共享的靜態(tài)實(shí)例:

class Program
{
    private static HttpClient client = new HttpClient();
    static void Main(string[] args)
    {
        Console.WriteLine("Starting connections");
        var g = GetAsync();
        g.Wait();
        Console.WriteLine("Connections done");
        Console.ReadKey();
    }
    static async Task GetAsync()
    {
        for (int i = 0; i < 5; i++)
        {
            var result = await client.GetAsync("http://aspnetmonsters.com/");
            Console.WriteLine(result.StatusCode);
        }
    }
}

應(yīng)用程序運(yùn)動(dòng)完畢之后,我們?cè)偻ㄟ^(guò)netstat工具打印出五個(gè)請(qǐng)求連接套接字狀態(tài),這時(shí)候會(huì)看到信息如下:

通過(guò)共享一個(gè)實(shí)例,減少了套接字的浪費(fèi),實(shí)際上由于套接字重用而傳輸快一點(diǎn)。
總結(jié):

  • 在創(chuàng)建HttpClient實(shí)例的時(shí)候,最好是靜態(tài)(static )實(shí)例。
  • 不要用using包裝HttpClient對(duì)象。

在.NET Core 2.1版本之后引入的 HttpClientFactory解決了HttpClient的所有痛點(diǎn)。有了 HttpClientFactory,我們不需要關(guān)心如何創(chuàng)建HttpClient,又如何釋放它。通過(guò)它可以創(chuàng)建具有特定業(yè)務(wù)的HttpClient,而且可以很友好的和 DI 容器結(jié)合使用,更為靈活。下面以 ASP.NET Core為例介紹HttpClientFactory的四種使用方式。

2.HttpClientFactory 的多種使用方式

可以通過(guò)多種使用方式在應(yīng)用程序中使用HttpClientFactory。

2.1使用基本用法

在Startup.ConfigureServices方法中,通過(guò)在IServiceCollection上調(diào)用AddHttpClient擴(kuò)展方法可以注冊(cè)IHttpClientFactory服務(wù)。
services.AddHttpClient();
注冊(cè)服務(wù)后,我們新建BasicUsageModel類使用IHttpClientFactory創(chuàng)建HttpClient實(shí)例:

public class BasicUsageModel
{
    private readonly IHttpClientFactory _clientFactory;
    public IEnumerable<GitHubBranch> Branches { get; private set; }
    public bool GetBranchesError { get; private set; }
    public BasicUsageModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
    public async Task OnGet()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "https://api.github.com/repos/aspnet/AspNetCore.Docs/branches");
        request.Headers.Add("Accept", "application/vnd.github.v3+json");
        request.Headers.Add("User-Agent", "HttpClientFactory-Sample");
        var client = _clientFactory.CreateClient();
        var response = await client.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
            Branches = await response.Content
                .ReadAsAsync<IEnumerable<GitHubBranch>>();
        }
        else
        {
            GetBranchesError = true;
            Branches = Array.Empty<GitHubBranch>();
        }
    }
}
public class GitHubBranch
{
    public string name { get; set; }
}

以這種方式直接在使用IHttpClientFactory的類中調(diào)用CreateClient方法創(chuàng)建HttpClient實(shí)例。然后在Controller中調(diào)用BasicUsageModel類:

public class HomeController : Controller
{
    private readonly IHttpClientFactory _clientFactory;
    public HomeController(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
    public IActionResult Index()
    {
        BasicUsageModel model = new BasicUsageModel(_clientFactory);
        var task = model.OnGet();
        task.Wait();
        List<GitHubBranch> list = model.Branches.ToList();
        return View(list);
    }
}

2.2使用命名客戶端

如果應(yīng)用程序需要有許多不同的HttpClient用法(每種用法的服務(wù)配置都不同),可以視情況使用命名客戶端??梢栽贖ttpClient中注冊(cè)時(shí)指定命名Startup.ConfigureServices的配置。

services.AddHttpClient("github", c =>
{
    c.BaseAddress = new Uri("https://api.github.com/");
    // Github API versioning
    c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
    // Github requires a user-agent
    c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});

上面的代碼調(diào)用AddHttpClient,同時(shí)提供名稱“github”。此客戶端應(yīng)用了一些默認(rèn)配置,也就是需要基址和兩個(gè)標(biāo)頭來(lái)使用GitHub API。每次調(diào)用CreateClient時(shí),都會(huì)創(chuàng)建HttpClient 的新實(shí)例,并調(diào)用配置操作。要使用命名客戶端,可將字符串參數(shù)傳遞到CreateClient。指定要?jiǎng)?chuàng)建的客戶端的名稱:

public class NamedClientModel : PageModel
{
    private readonly IHttpClientFactory _clientFactory;
    public IEnumerable<GitHubPullRequest> PullRequests { get; private set; }
    public bool GetPullRequestsError { get; private set; }
    public bool HasPullRequests => PullRequests.Any();
    public NamedClientModel(IHttpClientFactory clientFactory)
    {
        _clientFactory = clientFactory;
    }
    public async Task OnGet()
    {
        var request = new HttpRequestMessage(HttpMethod.Get,
            "repos/aspnet/AspNetCore.Docs/pulls");
        var client = _clientFactory.CreateClient("github");
        var response = await client.SendAsync(request);
        if (response.IsSuccessStatusCode)
        {
            PullRequests = await response.Content
                .ReadAsAsync<IEnumerable<GitHubPullRequest>>();
        }
        else
        {
            GetPullRequestsError = true;
            PullRequests = Array.Empty<GitHubPullRequest>();
        }
    }
}
public class GitHubPullRequest
{
    public string url { get; set; }
    public int? id { get; set; }
    public string node_id { get; set; }
}

在上述代碼中,請(qǐng)求不需要指定主機(jī)名。可以僅傳遞路徑,因?yàn)椴捎昧藶榭蛻舳伺渲玫幕?。在Controller中調(diào)用方法如上個(gè)示例。

2.3使用類型化客戶端

什么是“類型化客戶端”?它只是DefaultHttpClientFactory注入時(shí)配置的HttpClient。
下圖顯示了如何將類型化客戶端與HttpClientFactory結(jié)合使用:

類型化客戶端提供與命名客戶端一樣的功能,不需要將字符串用作密鑰。它們提供單個(gè)地址來(lái)配置特定HttpClient并與其進(jìn)行交互。例如,單個(gè)類型化客戶端可能用于單個(gè)后端終結(jié)點(diǎn),并封裝此終結(jié)點(diǎn)的所有處理邏輯。另一個(gè)優(yōu)勢(shì)是它們使用 DI 且可以被注入到應(yīng)用中需要的位置。
類型化客戶端在構(gòu)造函數(shù)中接收HttpClient參數(shù):

public class GitHubService
{
    public HttpClient Client { get; }
    public GitHubService(HttpClient client)
    {
        client.BaseAddress = new Uri("https://api.github.com/");
        // GitHub API versioning
        client.DefaultRequestHeaders.Add("Accept",
            "application/vnd.github.v3+json");
        // GitHub requires a user-agent
        client.DefaultRequestHeaders.Add("User-Agent",
            "HttpClientFactory-Sample");
        Client = client;
    }
    public async Task<IEnumerable<GitHubIssue>> GetAspNetDocsIssues()
    {
        var response = await Client.GetAsync(
"/repos/aspnet/AspNetCore.Docs/issues?state=open&sort=created&direction=desc");
        response.EnsureSuccessStatusCode();
        var result = await response.Content
            .ReadAsAsync<IEnumerable<GitHubIssue>>();
        return result;
    }
}
public class GitHubIssue
{
    public string url { get; set; }
    public int? id { get; set; }
    public string node_id { get; set; }
}

在上述代碼中,配置轉(zhuǎn)移到了類型化客戶端中。HttpClient對(duì)象公開為公共屬性??梢远x公開HttpClient功能的特定于API的方法。GetAspNetDocsIssues方法從GitHub存儲(chǔ)庫(kù)封裝查詢和分析最新待解決問(wèn)題所需的代碼。
要注冊(cè)類型化客戶端,可在Startup.ConfigureServices中使用通用的AddHttpClient擴(kuò)展方法,指定類型化客戶端類:

services.AddHttpClient<GitHubService>();

使用DI將類型客戶端注冊(cè)為暫時(shí)客戶端??梢灾苯硬迦牖蚴褂妙愋突蛻舳耍?/p>

public class TypedClientModel : PageModel
{
    private readonly GitHubService _gitHubService;
    public IEnumerable<GitHubIssue> LatestIssues { get; private set; }
    public bool HasIssue => LatestIssues.Any();
    public bool GetIssuesError { get; private set; }
    public TypedClientModel(GitHubService gitHubService)
    {
        _gitHubService = gitHubService;
    }
    public async Task OnGet()
    {
        try
        {
            LatestIssues = await _gitHubService.GetAspNetDocsIssues();
        }
        catch (HttpRequestException)
        {
            GetIssuesError = true;
            LatestIssues = Array.Empty<GitHubIssue>();
        }
    }
}

到此這篇關(guān)于ASP.NET Core使用IHttpClientFactory發(fā)出HTTP請(qǐng)求的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • .NET2.0版本中基于事件的異步編程模式(EAP)

    .NET2.0版本中基于事件的異步編程模式(EAP)

    這篇文章介紹了.NET2.0版本中基于事件的異步編程模式(EAP),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • ASP.NET?Core中Razor頁(yè)面的Handlers處理方法詳解

    ASP.NET?Core中Razor頁(yè)面的Handlers處理方法詳解

    本文詳細(xì)講解了ASP.NET?Core中Razor頁(yè)面的Handlers處理方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-02-02
  • ASP.NET Core中的Options選項(xiàng)模式

    ASP.NET Core中的Options選項(xiàng)模式

    這篇文章介紹了ASP.NET Core中的Options選項(xiàng)模式,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-04-04
  • Asp.Net 和 AJAX.Net 的區(qū)別

    Asp.Net 和 AJAX.Net 的區(qū)別

    Asp.Net 和 AJAX.Net 的區(qū)別...
    2007-03-03
  • WPF框架之Prism介紹

    WPF框架之Prism介紹

    這篇文章介紹了WPF的Prism框架,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-02-02
  • vs.net2008添加模板方法

    vs.net2008添加模板方法

    vs.net2008添加模板方法,需要的朋友可以參考一下
    2013-02-02
  • ASP.NET 中 Button、LinkButton和ImageButton 三種控件的使用詳解

    ASP.NET 中 Button、LinkButton和ImageButton 三種控件的使用詳解

    本文主要介紹Button、LinkButton和ImageButton 三種控件的使用方法,并一一舉例演示它們的用法,希望對(duì)大家有所幫助。
    2016-04-04
  • ASP.NET?Core中的Blazor組件介紹

    ASP.NET?Core中的Blazor組件介紹

    這篇文章介紹了ASP.NET?Core中的Blazor組件,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-03-03
  • ASP.NET樣板項(xiàng)目ABP框架的特性總結(jié)

    ASP.NET樣板項(xiàng)目ABP框架的特性總結(jié)

    這篇文章主要介紹了ASP.NET樣板項(xiàng)目ABP框架的特性總結(jié),ABP框架基于ASP.NET框架,用于開發(fā)Web應(yīng)用程序,需要的朋友可以參考下
    2016-06-06
  • .Net中控件的命名規(guī)則

    .Net中控件的命名規(guī)則

    這篇文章介紹了.Net中控件的命名規(guī)則,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-05-05

最新評(píng)論

花莲市| 阳东县| 邓州市| 志丹县| 瓦房店市| 榕江县| 永和县| 连云港市| 广德县| 奉新县| 济阳县| 当涂县| 象山县| 宝清县| 宜兴市| 万载县| 内丘县| 东丽区| 玛沁县| 岢岚县| 额敏县| 会宁县| 巩留县| 桐庐县| 马关县| 崇明县| 涟源市| 出国| 沾化县| 柳河县| 成都市| 青铜峡市| 双柏县| 临沭县| 页游| 双鸭山市| 曲靖市| 康保县| 丰县| 贵溪市| 汝阳县|