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

如何实现多线程并行发送带MaterialID的API Post请求并保存响应?

改造后的多线程异步请求代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Threading;

// 线程安全日志锁,避免多线程写入日志冲突
private static readonly object _logLock = new object();

public async Task ProcessMaterialsAsync()
{
    // 1. 读取MaterialID列表(优化读取效率)
    var materialIds = new List<string>();
    try
    {
        string[] lines = File.ReadAllLines(@"C:\Temp\Test.txt");
        foreach (var line in lines)
        {
            string trimmedId = line.Trim();
            if (!string.IsNullOrEmpty(trimmedId))
            {
                materialIds.Add(trimmedId);
                UpdateLogTxtSafe($"Material_Count = {trimmedId}");
            }
        }
    }
    catch (Exception ex)
    {
        UpdateLogTxtSafe($"读取ID文件失败:{ex.ToString()}");
        return;
    }

    // 确保输出目录存在,避免写入文件时出错
    string outputDir = @"C:\Temp\material";
    if (!Directory.Exists(outputDir))
    {
        Directory.CreateDirectory(outputDir);
        UpdateLogTxtSafe($"创建输出目录:{outputDir}");
    }

    // 2. 复用HttpClient(线程安全,避免频繁创建导致套接字耗尽)
    string fcsEndPoint = @"https://www.api.co.za";
    string fcsToken = textBoxDescription.Text.Trim();
    using (var httpClient = new HttpClient())
    {
        // 配置全局请求头,无需每次请求重复设置
        httpClient.DefaultRequestHeaders.Accept.Clear();
        httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("SessionToken", fcsToken);

        // 3. 异步并行处理所有MaterialID请求
        var tasks = new List<Task>();
        foreach (var id in materialIds)
        {
            tasks.Add(ProcessSingleMaterialAsync(id, httpClient, outputDir));
        }

        // 等待所有请求完成
        await Task.WhenAll(tasks);
        UpdateLogTxtSafe("所有MaterialID请求处理完成");
    }
}

private async Task ProcessSingleMaterialAsync(string materialId, HttpClient httpClient, string outputDir)
{
    UpdateLogTxtSafe($"提交请求 = {materialId}");
    try
    {
        string uri = $"{fcsEndPoint}/material/pageIndex={materialId}";
        // 异步发送POST请求(空内容直接用PostAsync,比PostAsJsonAsync更高效)
        using (var response = await httpClient.PostAsync(uri, null))
        {
            if (response.IsSuccessStatusCode)
            {
                string responseStr = await response.Content.ReadAsStringAsync();
                // 生成唯一文件名(时间戳精确到秒,避免重复)
                string fileName = Path.Combine(outputDir, $"Material_{materialId}_{DateTime.Now:yyyyMMddHHmmss}.txt");
                // 异步写入文件
                await File.WriteAllTextAsync(fileName, responseStr);
                UpdateLogTxtSafe($"请求成功,已写入文件:{fileName}");
            }
            else if (response.StatusCode == System.Net.HttpStatusCode.Forbidden)
            {
                UpdateLogTxtSafe($"请求失败(禁止访问) = {materialId},状态码:{response.StatusCode}");
            }
            else
            {
                UpdateLogTxtSafe($"请求失败 = {materialId},状态码:{response.StatusCode}");
            }
        }
    }
    catch (HttpRequestException hEx)
    {
        UpdateLogTxtSafe($"HTTP请求异常 = {materialId}:{hEx.ToString()}");
    }
    catch (Exception ex)
    {
        UpdateLogTxtSafe($"处理异常 = {materialId}:{ex.ToString()}");
    }
}

// 线程安全的日志更新方法
private void UpdateLogTxtSafe(string logMessage)
{
    lock (_logLock)
    {
        UpdateLogTxt(logMessage);
    }
}
关键改造说明
  • 复用HttpClient:原代码每次循环创建新HttpClient,会导致系统套接字耗尽。现在复用单个实例,它是线程安全的,能大幅提升请求效率。
  • 异步并行处理:用Task.WhenAll实现批量异步请求,相比同步循环,IO密集型场景下效率提升数倍,完美适配1000-5000个ID的批量处理需求。
  • 线程安全日志:给日志写入操作加锁,避免多线程同时写入导致的日志内容混乱或异常。
  • IO操作优化:用File.ReadAllLines一次性读取ID文件,异步写入响应文件,进一步提升整体处理速度。
  • 冗余代码清理:删除重复设置请求头的逻辑,简化URI拼接,清理不必要的变量声明,让代码更简洁。
  • 前置检查:提前创建输出目录,避免因目录不存在导致的文件写入失败。

注意:如果是WinForms/WPF环境,需将触发方法(如按钮点击事件)标记为async,避免阻塞UI线程:

private async void btnStartProcess_Click(object sender, EventArgs e)
{
    await ProcessMaterialsAsync();
}

内容的提问来源于stack exchange,提问作者M-Corp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 23:01:10