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

连续调用GenerateReportAsync方法触发RDLC数组越界错误求助

RDLC报表连续生成时触发“索引超出数组界限”错误

问题说明

本地报表处理报错:报表处理过程中发生意外错误:索引超出了数组界限。编写的GenerateReportAsync方法单次调用可正常生成文件流,但连续调用两次时必现该错误。

相关代码

报表生成方法

public byte[] GenerateReportAsync(string reportName, string reportType, Dictionary<string, string> parameters)
{
    string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Common", "Reports", reportName);
    Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
    Encoding.GetEncoding("utf-8");
    
    try
    {
        LocalReport report = new LocalReport(path);
        Dictionary<string, string> parameters2 = new Dictionary<string, string>(parameters);
        var result = report.Execute(GetRenderType(reportType), 1, parameters2);
        return result.MainStream;
    }
    catch (Exception ex)
    {
        var exception = ex.ToString();
    }
    return null;
}

调用逻辑

var getCertificateFileStream = GenerateReportAsync("CertificateWithBorder.rdlc", "pdf", parametersCertificate);
var getFileStream =  GenerateReportAsync("ReportWithBorder.rdlc", "pdf", reportParameter);

问题原因及修复方案

1. 重复注册编码提供程序引发冲突

每次调用方法都执行Encoding.RegisterProvider(CodePagesEncodingProvider.Instance),重复注册会导致编码模块内部状态混乱。

  • 修复:将这行代码移至程序初始化阶段(比如Main方法启动时、服务初始化逻辑中),仅执行一次。

2. LocalReport线程安全问题

LocalReport的实例创建与执行过程并非线程安全,连续快速调用会触发内部资源竞争,导致数组操作越界。

  • 修复方案1:添加线程锁隔离并发操作
    private static readonly object _reportLock = new object();
    public byte[] GenerateReportAsync(string reportName, string reportType, Dictionary<string, string> parameters)
    {
        string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Common", "Reports", reportName);
        
        lock(_reportLock)
        {
            try
            {
                using (LocalReport report = new LocalReport(path))
                {
                    Dictionary<string, string> parameters2 = new Dictionary<string, string>(parameters);
                    var result = report.Execute(GetRenderType(reportType), 1, parameters2);
                    return result.MainStream;
                }
            }
            catch (Exception ex)
            {
                var exception = ex.ToString();
            }
        }
        return null;
    }
    
  • 修复方案2:用using语句确保LocalReport实例及时释放,避免资源泄漏累积引发异常。

3. 额外检查点

确认外部调用时,传入的parametersCertificate和reportParameter字典没有被并发修改,虽然方法内已做字典复制,但原字典的并发修改仍可能间接影响处理逻辑。

验证步骤

  1. 迁移编码注册代码到初始化阶段,确保只执行一次;
  2. 应用锁或using资源管理逻辑;
  3. 再次连续调用报表生成方法,验证错误是否消除。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 15:40:17