asp.net mvc3 Web アプリで、遅い PDF レポートのいくつかについて時間を計っています。
特に1つは私たちの心を吹き飛ばしました...
SQL - 数百ミリ秒で返される RDLC 処理 - 数百ミリ秒 PDF 生成 - 4 分以上
そしてこれ: msdnページ2
RDLC を最適化して対処する方法を説明しましたが、C# コードで愚かなことをしていないことを確認したかったのです。
これは、RDLC を取得して PDF としてレンダリングするセクションです。非常に単純に見えますが、最適な方法で実行していますか? ベストプラクティスに従っていますか?
// build the byte stream
answerBytes = localViewer.Render(
args.ReportType, args.DeviceInfoXML, out mimeType, out encoding, out fnameExt,
out streamids, out warnings );
// send out vars back to client.
args.MineType = mimeType;
args.FnameExt = fnameExt;
// dispose of local viewer when complete
localViewer.Dispose();
netLogHdl.Trace( "Done PDF work " );
return answerBytes;
PDFの生成はとても悪いです何か間違ったことをしたに違いないと感じています...
PS ここでは、必要に応じてスタックの詳細を示します
public byte[] ByteStreamPdf(ref ByteStreamReportArgsCV args)
{
//The DeviceInfo settings should be changed based on the reportType
//http://msdn2.microsoft.com/en-us/library/ms155397.aspx
string deviceInfo = "<DeviceInfo>";
deviceInfo += "<OutputFormat>PDF</OutputFormat>";
if (args.Landscape)
{
deviceInfo += "<PageWidth>11in</PageWidth><PageHeight>8.5in</PageHeight>";
}
else
{
deviceInfo += "<PageWidth>8.5in</PageWidth><PageHeight>11in</PageHeight>";
}
deviceInfo += "<MarginTop>0.5in</MarginTop><MarginLeft>1in</MarginLeft>";
deviceInfo += "<MarginRight>1in</MarginRight><MarginBottom>0.5in</MarginBottom>";
deviceInfo += "</DeviceInfo>";
deviceInfo = "";
args.DeviceInfoXML = deviceInfo;
args.ReportType = "Pdf";
return ByteStreamReport(ref args);
}
public byte[] ByteStreamReport(ref ByteStreamReportArgsCV args)
{
Warning[] warnings;
string[] streamids;
string encoding;
string fnameExt;
string mimeType;
byte[] answerBytes;
LocalReport localViewer = new LocalReport();
// enable external images... CR # 20338 JK
localViewer.EnableExternalImages = true;
// build the Report Data Source
// open up your .rdlc in notepad look for <datasets> section in xml
// use what you find on the next line.
ReportDataSource rds = new ReportDataSource(args.NameOfDatasetInRdlc, args.DataToFillReport);
// set the report path and datasource
IWebAccess webAccessHdl = ObjectFactory.GetInstance<IWebAccess>();
//next line was HttpContext.Current.Request.MapPath(args.RdlcPathAndFname); changed to use webaccess - EWB
localViewer.ReportPath = webAccessHdl.GetMapPath(args.RdlcPathAndFname);
localViewer.DataSources.Add(rds);
// add parameters that rdlc needs
if (args.RptParameters != null)
localViewer.SetParameters(args.RptParameters);
//Sub Report Task
if (args.SubReportDataToFillReport != null)
{
for (int i = 0; i < args.SubReportDataToFillReport.Length; i++)
{
ReportDataSource subRds = new ReportDataSource(args.SubReportNameOfDatasetInRdlc[i],
args.SubReportDataToFillReport[i]);
localViewer.DataSources.Add(subRds);
}
if (args.SubReportDataToFillReport.Length > 0)
localViewer.SubreportProcessing +=
LoadSubreportProcessingEventHandler;
}
//End of Sub Report Task
// build the byte stream
answerBytes = localViewer.Render(
args.ReportType, args.DeviceInfoXML, out mimeType, out encoding, out fnameExt,
out streamids, out warnings);
// send out vars back to client.
args.MineType = mimeType;
args.FnameExt = fnameExt;
// dispose of local viewer when complete
localViewer.Dispose();
return answerBytes;
}