如何在C#中批量执行异步API方法?
可行性分析与实现方案
你想要的直接传入manager.CustomApi.UpsertOneAsync(new { })的调用方式不可行——因为调用该方法时会立即发起单个HTTP请求,无法拦截并提取请求的端点、参数、请求体等元数据用于批量处理。
以下是符合需求的正确实现方案:
核心思路
通过封装请求元数据的方式,先收集所有要批量执行的操作信息,再统一发送到API的批量端点,最后将批量响应映射回对应类型的结果。
步骤1:定义批量操作的元数据模型
用于描述每个要批量执行的请求信息:
// 单个批量操作的元数据 public class BatchOperation { public string Endpoint { get; set; } public HttpMethod Method { get; set; } public IDictionary<string, string> QueryParams { get; set; } = new Dictionary<string, string>(); public object RequestBody { get; set; } // 标记该操作对应的响应模型类型,用于后续反序列化 public Type ResponseType { get; set; } } // 批量API返回的单条响应结构(根据实际API返回调整) public class BatchApiResponseItem { public int StatusCode { get; set; } public object Data { get; set; } public string ErrorMessage { get; set; } }
步骤2:改造SubApi接口与实现类
在原有接口中新增构建批量操作元数据的方法,同时让原有单请求方法复用这些元数据逻辑:
interface ISubApi<T> where T : IResponseModel { // 原有单请求方法保留 Task<IResponse<T>> FindAllAsync(int offset = 0, int limit = 1000, IDictionary<string, string> @params = default); Task<IResponse<T>> FindOneAsync(IDictionary<string, string> @params = default); Task<IResponse<T>> UpsertOneAsync(object input); // 新增批量操作构建方法 BatchOperation BuildFindAllBatchOp(int offset = 0, int limit = 1000, IDictionary<string, string> @params = default); BatchOperation BuildFindOneBatchOp(IDictionary<string, string> @params = default); BatchOperation BuildUpsertOneBatchOp(object input); } // CustomApi实现示例 class CustomApi : ISubApi<CustomModel> { // 原有UpsertOneAsync复用批量构建逻辑 public async Task<IResponse<CustomModel>> UpsertOneAsync(object input) { var op = BuildUpsertOneBatchOp(input); // 单请求发送逻辑(基于op的元数据) ... } // 构建Upsert操作的批量元数据 public BatchOperation BuildUpsertOneBatchOp(object input) { return new BatchOperation { Endpoint = "/api/custom-resources", Method = HttpMethod.Post, RequestBody = input, ResponseType = typeof(CustomModel) }; } // 其他Build方法同理实现 public BatchOperation BuildFindAllBatchOp(int offset = 0, int limit = 1000, IDictionary<string, string> @params = default) { var op = new BatchOperation { Endpoint = "/api/custom-resources", Method = HttpMethod.Get, ResponseType = typeof(CustomModel) }; op.QueryParams.Add("offset", offset.ToString()); op.QueryParams.Add("limit", limit.ToString()); @params?.ToList().ForEach(p => op.QueryParams.Add(p)); return op; } public BatchOperation BuildFindOneBatchOp(IDictionary<string, string> @params = default) { return new BatchOperation { Endpoint = "/api/custom-resources/single", Method = HttpMethod.Get, QueryParams = @params ?? new Dictionary<string, string>(), ResponseType = typeof(CustomModel) }; } }
步骤3:实现批量执行管理器
创建BatchManager类,负责接收批量操作元数据、发送批量请求并映射结果:
public class BatchManager { private readonly HttpClient _httpClient; public BatchManager(HttpClient httpClient) { _httpClient = httpClient; } public async Task<IReadOnlyList<IResponse<object>>> ExecuteAsync(params BatchOperation[] operations) { // 构造符合API要求的批量请求体(根据实际API格式调整) var batchRequest = new { operations = operations.Select(op => new { path = op.Endpoint, method = op.Method.ToString(), query_params = op.QueryParams, body = op.RequestBody }) }; // 发送批量请求 var response = await _httpClient.PostAsJsonAsync("/api/batch", batchRequest); response.EnsureSuccessStatusCode(); var rawResponses = await response.Content.ReadFromJsonAsync<List<BatchApiResponseItem>>(); var results = new List<IResponse<object>>(); // 将批量响应映射为SDK的IResponse格式 for (int i = 0; i < operations.Length; i++) { var op = operations[i]; var rawResp = rawResponses[i]; var data = JsonSerializer.Deserialize(rawResp.Data, op.ResponseType); results.Add(new Response<object> // 假设Response是IResponse<T>的实现类 { Data = data, StatusCode = rawResp.StatusCode, ErrorMessage = rawResp.ErrorMessage }); } return results; } }
步骤4:更新Manager类
添加Batch属性,整合批量能力:
class Manager { public ISubApi<CustomModel> CustomApi { get; private set; } public ISubApi<OtherCustomModel> OtherCustomApi { get; private set; } public BatchManager Batch { get; private set; } public Manager(HttpClient httpClient) { CustomApi = new CustomApi(); OtherCustomApi = new OtherCustomApi(); Batch = new BatchManager(httpClient); } }
最终使用方式
var manager = new Manager(new HttpClient()); // 构建批量操作元数据 var customUpsertOp = manager.CustomApi.BuildUpsertOneBatchOp(new { Name = "Test Custom" }); var otherUpsertOp = manager.OtherCustomApi.BuildUpsertOneBatchOp(new { Value = 123 }); // 执行批量请求 var batchResults = await manager.Batch.ExecuteAsync(customUpsertOp, otherUpsertOp); // 处理结果 var customResult = batchResults[0] as IResponse<CustomModel>; var otherResult = batchResults[1] as IResponse<OtherCustomModel>;
内容的提问来源于stack exchange,提问作者plotkabytes
相关产品推荐
相关产品推荐

