main
wanggaofeng 12 months ago
parent a7ce33dd5f
commit 0786050265

@ -0,0 +1,92 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"## HttpClient 概述"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 作用"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## 整体理解"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 前世今生"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## 架构图"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 相关资源"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -0,0 +1,58 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
}
},
"source": [
"# HttpClient 使用原则"
]
},
{
"cell_type": "markdown",
"metadata": {
"dotnet_interactive": {
"language": "csharp"
},
"polyglot_notebook": {
"kernelName": "csharp"
},
"vscode": {
"languageId": "polyglot-notebook"
}
},
"source": [
"## 1、复用"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".NET (C#)",
"language": "C#",
"name": ".net-csharp"
},
"language_info": {
"name": "python"
},
"polyglot_notebook": {
"kernelInfo": {
"defaultKernelName": "csharp",
"items": [
{
"aliases": [],
"name": "csharp"
}
]
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -11,6 +11,7 @@ global using System.Net.Http;
global using System.Net.Http.Json;
global using System.Net.Http.Headers;
global using HttpClientStudy.Config;
global using HttpClientStudy.Model;
global using HttpClientStudy.Core;

@ -3,7 +3,7 @@
/// <summary>
/// 简单 HttpClient 包装类
/// </summary>
public class SimpleHttpClient
public class BaseHttpClient
{
#region Get请求
public string Get(string url)

@ -30,11 +30,11 @@ namespace HttpClientStudy.Core
/// </list>
/// </summary>
/// <remarks>
/// 简化处理
/// 错误处理
/// </remarks>
public class HttpError
{
// 定义一个 HttpClient 实例,共享
// 定义一个 HttpClient 共享实例
public static HttpClient HttpClient = new HttpClient(new SocketsHttpHandler() { PooledConnectionLifetime = TimeSpan.FromMinutes(1) })
{
BaseAddress = new Uri(WebApiConfigManager.GetWebApiConfig().BaseUrl)
@ -61,7 +61,6 @@ namespace HttpClientStudy.Core
{
var response = await HttpClient.GetAsync("http://localhost:30");
}
catch (Exception ex)
{
// 捕获异常,处理

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.Core.Utils
{
/// <summary>
/// 启动工具类
/// </summary>
public static class StartupUtility
{
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
public static void StartWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi项目不在运行状态则启动webapi项目
if (webAppIsRunningByMutex() == false)
{
//VS项目根目录
string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;
//webapi项目根项目
string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);
//启动命令信息
var prossInfo = new System.Diagnostics.ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
{
UseShellExecute = true,
CreateNoWindow = false,
RedirectStandardOutput = false
};
//启动
System.Diagnostics.Process.Start(prossInfo);
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
}
/// <summary>
/// 关闭webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
public static void ExitWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi为运行状态则关闭
if (webAppIsRunningByMutex())
{
var webApiProcess = System.Diagnostics.Process.GetProcessesByName(projectAndMutexName);
if (webApiProcess != null && webApiProcess.Length>0)
{
webApiProcess[0].Kill();
}
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
}
}
}

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.UnitTest.Fixtures
{
[CollectionDefinition("App")]
public class AppCollectionFixture : ICollectionFixture<AppFixture>
{
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HttpClientStudy.UnitTest.Fixtures
{
public class AppFixture : IDisposable
{
public AppFixture()
{
}
public void Dispose()
{
}
}
}

@ -43,8 +43,4 @@
<ProjectReference Include="..\HttpClientStudy.WebApp\HttpClientStudy.WebApp.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="HttpRequests\" />
</ItemGroup>
</Project>

@ -3,10 +3,10 @@
/// <summary>
/// SimpleHttpClient 测试类
/// </summary>
public class SimpleHttpClientTest
public class BaseHttpClientTest
{
private readonly ITestOutputHelper _logger;
public SimpleHttpClientTest(ITestOutputHelper outputHelper)
public BaseHttpClientTest(ITestOutputHelper outputHelper)
{
_logger = outputHelper;
}
@ -14,7 +14,7 @@
[Fact]
public void Get_Test()
{
SimpleHttpClient client = new SimpleHttpClient();
BaseHttpClient client = new BaseHttpClient();
var result = client.Get(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount");
@ -25,7 +25,7 @@
[Fact]
public void GetJson_Test()
{
SimpleHttpClient client = new SimpleHttpClient();
BaseHttpClient client = new BaseHttpClient();
var result = client.GetJson<BaseResult<string>>(WebApiConfigManager.GetWebApiConfig().BaseUrl + "/api/Simple/GetAccount");

@ -24,14 +24,6 @@ namespace HttpClientStudy.UnitTest.HttpResponses
client.PostAsync("http://www.baidu.com", content);
}
[Fact]
public async void Test2()
{
HttpClient client = new HttpClient();
var dd = await client.PostAsJsonAsync("url", new { Name = "" }, CancellationToken.None);
}
}
public class Demo

@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace HttpClientStudy.UnitTest
{
public class StartupTest
{
[Fact]
public void StartWebApiProject()
{
}
}
}

@ -1,5 +1,7 @@
using System.Diagnostics;
using HttpClientStudy.Core.Utils;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
@ -41,18 +43,18 @@ namespace HttpClientStudy.UnitTest
public void ConfigureHost(IHostBuilder hostBuilder)
{
//确保启动 webapi 项目
StartWebApiProject();
StartupUtility.StartWebApiProject();
hostBuilder
//主机配置
//主机配置设置
.ConfigureHostConfiguration(builder =>
{
})
//应用配置
//应用配置设置
.ConfigureAppConfiguration((context, builder) =>
{
})
//配置Web主机
.ConfigureWebHost(webHostBuilder =>
@ -65,21 +67,16 @@ namespace HttpClientStudy.UnitTest
})
.ConfigureTestServices(a =>
{
Console.WriteLine("+++++++++++++++++++++++++++++++++");
a.BuildServiceProvider().GetRequiredService<IHostApplicationLifetime>().ApplicationStopping.Register(() =>
{
Console.WriteLine("=========================");
});
})
.UseStartup<WebApiStartup>();
//配置默认配置项
//webHostBuilder.ConfigureAppConfiguration((context, configBuilder) =>
//{
// configBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
// configBuilder.AddJsonFile($"appsettings.{context.HostingEnvironment.EnvironmentName}.json", optional: true, reloadOnChange: true);
//});
//webHostBuilder.ConfigureServices(services =>
//{
// services.AddHealthChecks();
//});
.UseStartup<WebApiStartup>()
;
});
}
@ -89,62 +86,10 @@ namespace HttpClientStudy.UnitTest
/// <param name="services"></param>
public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{
Debugger.Log(1, "DI", "ConfigureServices");
}
/// <summary>
/// 启动webapi项目
/// (出现webapi项目启动命令行窗口)
/// </summary>
private void StartWebApiProject()
{
string projectAndMutexName = WebApiConfigManager.GetWebApiConfigOption().CurrentValue.WebAppMutexName;
//webapi项目不在运行状态则启动webapi项目
if (webAppIsRunningByMutex() == false)
{
//VS项目根目录
string vsProjectPath = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory)!.Parent!.Parent!.Parent!.Parent!.FullName;
//webapi项目根项目
string webApiProjectPath = Path.Combine(vsProjectPath, projectAndMutexName);
//启动命令信息
var prossInfo = new ProcessStartInfo("dotnet", $"run --project {webApiProjectPath}")
{
UseShellExecute = true,
CreateNoWindow = false,
RedirectStandardOutput = false
};
//启动
Process.Start(prossInfo);
}
//由进程名判断
//bool webAppIsRunningByProcessName()
//{
// return Process.GetProcessesByName(projectAndMutexName).ToList().Count == 0;
//}
//由互斥锁判断
bool webAppIsRunningByMutex()
services.BuildServiceProvider().GetRequiredService<IHostApplicationLifetime>().ApplicationStopping.Register(() =>
{
bool createdResult = true;
//创建互斥锁
using (var mutex = new Mutex(true, projectAndMutexName, out createdResult))
{
if (createdResult)
{
mutex.ReleaseMutex();
}
}
//互斥锁是否创建成功
return !createdResult;
}
Console.WriteLine("=========================");
});
}
private class WebApiStartup
@ -156,7 +101,7 @@ namespace HttpClientStudy.UnitTest
public void Configure(IApplicationBuilder app)
{
app.Run(static context => context.Response.WriteAsync("xxxxxx"));
}
}
}

@ -1,3 +1,7 @@
using System.Diagnostics;
using HttpClientStudy.Core.Utils;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
@ -20,4 +24,36 @@ app.UseAuthorization();
app.MapControllers();
Process currentProcess = Process.GetCurrentProcess();
currentProcess.EnableRaisingEvents = true;
currentProcess.Exited += (s, r) =>
{
Console.WriteLine("000000000000000000000000000000000000");
};
// 获取 IHostApplicationLifetime 实例
var applicationLifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
// 注册应用程序关闭事件
applicationLifetime.ApplicationStopping.Register(() =>
{
//关闭WebApi
StartupUtility.ExitWebApiProject();
});
applicationLifetime.ApplicationStopped.Register(() => {
Console.WriteLine("xxxxxxxxxxxxxxxxxxxx");
});
// 注册 AppDomain 的未处理异常事件
AppDomain.CurrentDomain.UnhandledException += (s,e)=>
{
Console.WriteLine("退出");
};
//确保启动WebApi程序
StartupUtility.StartWebApiProject();
app.Run();

Loading…
Cancel
Save