I use Linq2Sql to retrieve a list of ID’s that I use to launch a SSRS report export wia SSRS web service.
The query retrieves about 200 items and I use a foreach loop to loop through them.
I pass the List object containing the ID’s to a method executed in a new thread.
The SSRS report generation is quite long, so sometimes when the server goes slower due to work load, the overall execution execeedes the 20 minutes and my threads ends, with no exception.
Is there a timeout setting in Linq2Sql DataContext that matches this use case, after which my results become unavailable and the foreach loop ends?
Update 1 (the code):
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);
}
}
Update 2:
The rs object (of a custom ReportService class I made to separate report WS calls) is not in the same scope of the thread; it’s declared and instantiated outside the method launched as a thread and the class containing the method and the rs declaration is an MVC 3 controller.
In the ReportService class every call instantiates a new ReportExecutionService (previously obtained by a web reference to ReportExecution2005.asmx).
Update 3 (the WS call code and a little update in the first part of code):
I refactored the code to have a static call to my ReportServiceImpl‘s method and applying what’s told in @JamieSee’s response that may exclude timeout in Linq2Sql.
This is the ReportServiceImpl.WSReport actual implementation; after 20 minutes it stops without exceptions at 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;
}
Testing with the multiple thread configuration mentioned in a comment above and going deeper into this issue, I found the correct answer to it, so I’m reporting it here for completeness.
The reason for this subtle timeout, resides in the Idle Time-out configuration in the Process Model section of the Advanced Settings of the Application Pool.
It’s default value is 20 minutes.
For some reason that I yet don’t understand, a process initiated from the web layer that launches some threads, if there’s no web layer activity is treated as Idle and then stopped. It can be seen even following the behaviour of the w3wp.exe process in the Processes tab in Task Manager.
Any threads, queued in a ThreadPool or launched directly by this process will end with the process.
At the end I can say it’s not Linq2Sql related and not SRSS web services related, but more IIS process model related.