我使用 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;
}