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

SSIS脚本组件调用Azure翻译API触发BufferDisconnectedException的问题及异步方法整合咨询

解决SSIS脚本组件中调用Azure翻译API的BufferDisconnectedException问题

你的问题核心在于SSIS脚本组件的同步执行上下文和异步API调用的冲突——你用了async void修饰Input0_ProcessInputRow方法,这会导致SSIS运行时误以为行处理已经完成,提前释放输入缓冲区,而此时你的异步翻译请求还在后台运行,最终触发Dts.Pipeline.BufferDisconnectedException。

微软官方示例用async Task Main是因为控制台程序支持异步入口点,但SSIS的Input0_ProcessInputRow是固定的同步方法签名,不能直接用async void(这种写法只适合事件处理场景,非事件场景下会丢失任务跟踪能力)。

解决方案:将异步API调用同步化

我们可以把翻译逻辑封装成异步方法,然后在同步的Input0_ProcessInputRow中同步等待异步操作完成,避免SSIS提前释放缓冲区。以下是修正后的完整代码:

public class ScriptMain : UserComponent {
    private static readonly string subscriptionKey = "###########";
    private static readonly string endpoint = "https://api.cognitive.microsofttranslator.com";
    private static readonly string location = "global";

    // 封装异步翻译逻辑
    private static async Task<string> TranslateTextAsync(string textToTranslate)
    {
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        string route = "/translate?api-version=3.0&from=de&to=en";
        object[] body = new object[] { new { Text = textToTranslate } };
        var requestBody = JsonConvert.SerializeObject(body);

        using (var client = new HttpClient())
        using (var request = new HttpRequestMessage())
        {
            request.Method = HttpMethod.Post;
            request.RequestUri = new Uri(endpoint + route);
            request.Content = new StringContent(requestBody, Encoding.UTF8, "application/json");
            request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
            request.Headers.Add("Ocp-Apim-Subscription-Region", location);

            HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false);
            return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
        }
    }

    public override void Input0_ProcessInputRow(Input0Buffer Row)
    {
        try
        {
            // 同步等待异步操作完成,确保SSIS不会提前释放缓冲区
            string translationResult = TranslateTextAsync(Row.TextToTranslate).GetAwaiter().GetResult();
            Row.TranslationFromAPI = translationResult;
        }
        catch (Exception ex)
        {
            // 可选:添加错误处理,比如记录错误信息到输出列
            Row.ErrorDescription = $"翻译失败:{ex.Message}";
            // 标记此行错误(如果需要让SSIS路由到错误输出)
            // Row.DirectRowToErrorOutput();
        }
    }
}

关键细节说明:

  • 避免async void:async void会让方法在第一个await时立即返回,SSIS会认为行处理完成并释放缓冲区,后续异步操作完成后再访问Row就会报错。
  • 使用GetAwaiter().GetResult():相比.Wait(),它会直接抛出原始异常,便于调试;配合ConfigureAwait(false)可以避免上下文死锁风险。
  • 错误处理:添加try-catch块可以防止单个行的翻译失败导致整个数据流任务崩溃,同时可以把错误信息写入自定义列,方便后续排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 14:52:48