0

我使用 Linq2Sql 检索 ID 列表,用于通过 SSRS Web 服务启动 SSRS 报告导出。该查询检索大约 200 个项目,我使用 foreach 循环遍历它们。

我将包含 ID 的 List 对象传递给在新线程中执行的方法。

SSRS 报告的生成时间很长,所以有时当服务器由于工作负载变慢时,整体执行超过了20 分钟,我的线程也结束了,无一例外。

Linq2Sql DataContext 中是否有与此用例匹配的超时设置,之后我的结果变得不可用并且 foreach 循环结束?

更新 1(代码):

List<String> list = dc.ListaIDs().ToList<String>();
int count = 0;
foreach (var item in list)
{
    string FileName = "report_" + (++count).ToString() + ".pdf";
    LoggerUtility.Instance.log.Debug(String.Format("export => " + FileName));
    try
    {
        switch (ReportFormat)
        {
            case "PDF":
                risultato = ReportServiceImpl.WSReport("PDF", item);
                System.IO.File.WriteAllBytes(FileName, risultato.PDFResult);
                break;
            default:
                LoggerUtility.Instance.log.Warn("no format");
                break;
        }
    }
    catch (Exception ex)
    {
        LoggerUtility.Instance.log.Warn("error exporting => " + FileName, ex);
    }
}

更新 2:

rs 对象(我为分离报告 WS 调用而创建的自定义 ReportService 类)不在线程的同一范围内;它在作为线程启动的方法之外声明和实例化,包含该方法的类和 rs 声明是 MVC 3 控制器。

在 ReportService 类中,每个调用都会实例化一个新的 ReportExecutionService(之前通过对 ReportExecution2005.asmx 的 Web 引用获得)。

更新 3(WS 调用代码和第一部分代码的一点更新):

我重构了代码以对我ReportServiceImpl的方法进行静态调用,并应用@JamieSee 的响应中所说的可能排除Linq2Sql 中的超时。这是 ReportServiceImpl.WSReport 的实际实现;20 分钟后,它无一例外地停在result = service.Render(...)

public static ReportResult WSReport(String format, string id)
{
    ReportResult _return = new ReportResult();
    ReportExecution.ReportExecutionService service = null;
    try
    {
        byte[] result;
        service = new ReportExecution.ReportExecutionService();

        String reportPath = @"/myReport";
        string historyID = null;

        service.UseDefaultCredentials = true;

        //load report
        ExecutionInfo execInfo = new ExecutionInfo();
        ExecutionHeader execHeader = new ExecutionHeader();

        service.ExecutionHeaderValue = execHeader;
        execInfo = service.LoadReport(reportPath, historyID);

        //set execution parameter
        ParameterValue[] parameters = new ParameterValue[1];
        parameters[0] = new ParameterValue() { Name = "id", Value = id };
        service.SetExecutionParameters(parameters, "it-IT");

        String SessionId = service.ExecutionHeaderValue.ExecutionID;

        //render report actually
        String deviceInfo = "";
        String extension;
        String mimetype;
        String encoding;
        GestioneVIP_Services.ReportExecution.Warning[] warnings;
        string[] streams;
        result = service.Render(format, deviceInfo, out extension, out mimetype, out encoding, out warnings, out streams);
        switch (format)
        {
            case Constants.EXCEL_FORMAT:
                _return.XLSResult = result;
                break;
            case Constants.PDF_FORMAT:
                _return.PDFResult = result;
                break;
            case Constants.HTML_FORMAT:
                _return.HTMLResult = result;
                break;
        }
    }
    catch (SoapException ex)
    {
        LoggerUtility.Instance.log.Error(String.Format("{0}/n{1}", ex.Message, ex.StackTrace));
    }
    catch (Exception ex)
    {
        LoggerUtility.Instance.log.Error(String.Format("{0}/n{1}", ex.Message, ex.StackTrace));
    }
    finally
    {
        if (service != null)
        {
            service.Dispose();
        }
    }
    return _return;
}
4

2 回答 2

1

尝试更改 IEnumerable list = dc.ListaIDs(); 列表列表 = dc.ListaIDs().ToList();。这应该避免在 foreach 中延迟执行,并且会告诉您这是 Linq 问题还是其他问题。

于 2012-08-06T16:53:36.413 回答
0

使用上面评论中提到的多线程配置进行测试并深入研究这个问题,我找到了正确的答案,所以我在这里报告它的完整性。

这种微妙超时的原因在于应用程序池的高级设置进程模型部分中的空闲超时配置。

它的默认值为20 分钟

由于某种我还不明白的原因,从启动一些线程的 Web 层启动的进程,如果没有 Web 层活动被视为空闲然后停止。甚至可以在任务管理器的进程选项卡中跟踪w3wp.exe进程的行为。 任何在 ThreadPool 中排队或由该进程直接启动的线程都将以该进程结束。

最后我可以说它不是 Linq2Sql 相关的,也不是 SRSS Web 服务相关的,而是更多的 IIS 进程模型相关的。

于 2012-10-12T09:04:10.580 回答