diff --git a/Docs/1.2.使用准则.ipynb b/Docs/1.2.使用准则.ipynb index e9e3127..22d9485 100644 --- a/Docs/1.2.使用准则.ipynb +++ b/Docs/1.2.使用准则.ipynb @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -712,7 +712,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 29, "metadata": { "dotnet_interactive": { "language": "csharp" @@ -724,7 +724,24 @@ "languageId": "polyglot-notebook" } }, - "outputs": [], + "outputs": [ + { + "data": { + "text/html": [ + "
Installed Packages
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "共有9193个字符\r\n" + ] + } + ], "source": [ "#r \"nuget:Polly\"\n", "#r \"nuget:Microsoft.Extensions.Http.Resilience\"\n", diff --git a/Docs/1.3.0.基础使用.管理客户端.ipynb b/Docs/1.3.0.基础使用.管理客户端.ipynb index 3f5e1eb..ed547b1 100644 --- a/Docs/1.3.0.基础使用.管理客户端.ipynb +++ b/Docs/1.3.0.基础使用.管理客户端.ipynb @@ -20,7 +20,31 @@ "source": [ "HttpClient 旨在实例化一次,并在应用程序的整个生命周期内重复使用。\n", "\n", - "为实现复用,HttpClient类库默认使用连接池和请求管道,可以再结合IoC容器、工厂模式(提供了IHttpClientFactory类库)、复原库Polly" + "为实现复用,HttpClient类库默认使用连接池和请求管道,可以手动管理(连接池、配置管道、使用Polly); 结合IoC容器、工厂模式(提供了IHttpClientFactory类库)、复原库Polly,可以更加方便、完善的使用,这也是推荐的方法。" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], + "source": [ + "//全局设置,行运行一次,为后续准备\n", + "#r \"nuget:System.Net.Http.Json\"\n", + "#r \"nuget:Microsoft.Extensions.DependencyInjection\"\n", + "\n", + "global using System.Net.Http;\n", + "global using System.Net.Http.Headers;\n" ] }, { @@ -40,6 +64,64 @@ "## 1、手动管理:直接实例化-强烈不推荐" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "下面这种每次使用都实例化的用法是最常见、最`不推荐的`:\n", + "\n", + "因为HttpClient刚推出时不成熟及微软官方文档的示例代码是这种用法,再加上这种是最简单方便的使用方法,就造成很多人使用这种用法。\n", + "这种方法有如下缺点:\n", + "+ 1. 每次使用都实例化,造成性能开销大、容易内存泄露;\n", + "+ 2. 并发量大、请求频繁时:网络端口会被耗尽 `Using包HttpClient,也只是在应用进程中释放了HttpClient实例,但http请求/响应是跨操作系统和网络的,而系统及网络问题在进程之上,不是进程所能处理的。`\n", + " \n", + "优点:\n", + "+ 1. 使用简单,好学易用;\n", + "+ 2. 并发量小且请求不频繁时,问题不大;" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "dotnet_interactive": { + "language": "csharp" + }, + "polyglot_notebook": { + "kernelName": "csharp" + }, + "vscode": { + "languageId": "polyglot-notebook" + } + }, + "outputs": [], + "source": [ + "/*\n", + " 每次请求都实例化:并发量大、请求频繁进会耗尽套接字端口\n", + "*/\n", + "{ \n", + " using(var client = new HttpClient())\n", + " {\n", + " //发送请求\n", + " var response = await client.GetAsync(\"http://localhost\");\n", + " response.EnsureSuccessStatusCode();\n", + " }\n", + "\n", + " //显示句柄\n", + " var displayValue = display($\"第 1 次请求,成功!\");\n", + "\n", + " for(int i=0;i<10;i++)\n", + " {\n", + " using(var client = new HttpClient())\n", + " {\n", + " var response = await client.GetAsync(\"http://localhost\");\n", + " response.EnsureSuccessStatusCode();\n", + " displayValue.Update($\"第 {i+1} 次/ 共 10 次请求,成功!\");\n", + " }\n", + " }\n", + "}" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -58,7 +140,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## 4、手动管理 + 可复原(Polly)" + "## 4、手动管理:可复原(Polly)请求" ] }, { diff --git a/HttpClientStudy.Core/HttpError.cs b/HttpClientStudy.Core/HttpError.cs index 72ea0ed..6a19307 100644 --- a/HttpClientStudy.Core/HttpError.cs +++ b/HttpClientStudy.Core/HttpError.cs @@ -1,6 +1,7 @@ using HttpClientStudy.Config; using Microsoft.Extensions.Options; +using System.Net.Http.Json; namespace HttpClientStudy.Core {