You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:54:57