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

如何将Process调用重构为HttpClient实现HTML文件翻译

重构建议:用HttpClient替代Process调用curl实现HTML翻译

问题背景

现有异步函数TranslateHTMLFileAsync通过调用curl命令完成HTML文件翻译,包含上传文档、轮询翻译状态、下载翻译结果三个核心步骤。目前仅下载步骤使用了HttpClient,需将上传和轮询部分也改用HttpClient重构,优化代码的可靠性与可维护性。

函数参数说明:

  • htmlfile:待翻译的HTML文件
  • target_language:目标翻译语言
  • checkOutTime:翻译处理超时时间(默认90秒)

核心重构点

1. 复用HttpClient实例

避免每次请求创建新的HttpClient,使用静态实例(或依赖注入管理),防止socket资源耗尽。

2. 替换文档上传的curl调用

用MultipartFormDataContent构造表单数据,对应curl的-F参数实现文件上传。

3. 替换状态轮询的curl调用

用FormUrlEncodedContent构造POST参数,对应curl的-d参数,替代Process调用。

4. 优化超时逻辑

用CancellationTokenSource实现精准超时控制,替代基于DateTime的判断。

5. 严谨错误处理

直接反序列化API响应,避免通过字符串包含判断结果,提升代码稳定性。

完整重构代码

首先补充CheckDocumentResponse类定义:

public class CheckDocumentResponse
{
    public string status { get; set; }
    // 可根据API实际返回添加其他字段
}

重构后的TranslateHTMLFileAsync方法:

// 静态HttpClient实例,复用连接池
private static readonly HttpClient _httpClient = new HttpClient();

public static async Task<string> TranslateHTMLFileAsync(FileInfo htmlfile, Language target_language, int checkOutTime = 90)
{
    var target_lang = target_language.ToString();
    if (string.IsNullOrEmpty(target_lang))
        throw new Exception("目标语言不支持");
    if (!htmlfile.Extension.ToLowerInvariant().EndsWith(".htm") && !htmlfile.Extension.ToLowerInvariant().EndsWith(".html"))
        throw new Exception("提供的文件不是HTML格式");

    string key = GlobalSetting.Get("APIKeys").StringValue;

    // 1. 上传文档
    UploadDocumentResponse uploadResponse;
    using (var content = new MultipartFormDataContent())
    {
        // 添加文件内容
        using (var fileStream = htmlfile.OpenRead())
        {
            var fileContent = new StreamContent(fileStream);
            content.Add(fileContent, "file", htmlfile.Name);
        }
        // 添加其他表单参数
        content.Add(new StringContent(key), "auth_key");
        content.Add(new StringContent(target_lang), "target_lang");

        var uploadResponseMessage = await _httpClient.PostAsync("https://devapi.com/v2/document", content);
        uploadResponseMessage.EnsureSuccessStatusCode(); // 自动处理HTTP错误状态码

        var uploadResponseBody = await uploadResponseMessage.Content.ReadAsStringAsync();
        uploadResponse = Functions.DeserializeJSON<UploadDocumentResponse>(uploadResponseBody);

        if (uploadResponse == null || string.IsNullOrEmpty(uploadResponse.document_id))
            throw new Exception($"文档上传失败,响应内容:{uploadResponseBody}");
    }

    // 2. 轮询翻译状态
    CheckDocumentResponse checkResponse;
    using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(checkOutTime));
    await Task.Delay(5000, cts.Token); // 初始等待5秒

    while (true)
    {
        await Task.Delay(1000, cts.Token); // 每次轮询间隔1秒

        var checkFormContent = new FormUrlEncodedContent(new Dictionary<string, string>
        {
            { "auth_key", key },
            { "document_key", uploadResponse.document_key }
        });

        var checkResponseMessage = await _httpClient.PostAsync($"https://devapi.com/v2/document/{uploadResponse.document_id}", checkFormContent);
        checkResponseMessage.EnsureSuccessStatusCode();

        var checkResponseBody = await checkResponseMessage.Content.ReadAsStringAsync();
        checkResponse = Functions.DeserializeJSON<CheckDocumentResponse>(checkResponseBody);

        if (checkResponse == null || string.IsNullOrEmpty(checkResponse.status))
            throw new Exception($"查询文档状态失败,响应内容:{checkResponseBody}");
        if (checkResponse.status == "error")
            throw new Exception("文档翻译失败");
        if (checkResponse.status == "done")
            break;
    }

    // 3. 下载翻译结果
    var resultFormContent = new FormUrlEncodedContent(new Dictionary<string, string>
    {
        { "document_key", uploadResponse.document_key },
        { "auth_key", key }
    });

    var resultResponseMessage = await _httpClient.PostAsync($"https://devapi.com/v2/document/{uploadResponse.document_id}/result", resultFormContent);
    resultResponseMessage.EnsureSuccessStatusCode();

    return await resultResponseMessage.Content.ReadAsStringAsync();
}

重构优势

  • 性能提升:复用HttpClient连接池,减少TCP连接开销
  • 可靠性增强:EnsureSuccessStatusCode自动处理HTTP错误,CancellationToken精准控制超时
  • 可维护性提升:统一使用HttpClient,避免Process调用的字符串拼接与平台依赖
  • 错误处理更严谨:直接反序列化响应对象,避免字符串匹配的脆弱逻辑

内容的提问来源于stack exchange,提问作者user3920526

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 20:23:09