将水晶报表导出为pdf流时出现访问问题。下面是在ASP.net MVC Web应用程序中的后台任务中运行的代码:
using (var memoryStream = new MemoryStream())
using (var stream = reportDoc.ExportToStream(ExportFormatType.PortableDocFormat))
{
stream.CopyTo(memoryStream);
data = memoryStream.ToArray();
}
以下是异常的堆栈跟踪:
System.Runtime.InteropServices.COMException (0x80004005): The process cannot access the file because it is being used by another process.
at CrystalDecisions.ReportAppServer.Controllers.ReportSourceClass.Export(ExportOptions pExportOptions, RequestContext pRequestContext)
at CrystalDecisions.ReportSource.EromReportSourceBase.ExportToStream(ExportRequestContext reqContext)
at CrystalDecisions.CrystalReports.Engine.FormatEngine.ExportToStream(ExportRequestContext reqContext)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportOptions options)
at CrystalDecisions.CrystalReports.Engine.ReportDocument.ExportToStream(ExportFormatType formatType)
如何解决这个问题?
答案 0 :(得分:2)
主要问题是你对水晶医生的记忆。因此,每次导出后,您必须清理对象,清除缓存和GAC。
首先检查上面的链接,我搜索并找到一个如下(click here to know more)。
像往常一样偶尔出现的错误,很难说。在99%的情况下,SP无法解决问题。你没有说的一件事是你如何从这个错误中恢复过来?重启应用?重新启动吗?
我首先查看%temp%文件夹,看看是否有任何孤立的CR临时文件。如果有的话,你需要考虑为什么这些会成为孤儿。
查看事件查看器。有错误吗?警告?
确保在完成这些操作后,在报表对象上使用.Close和.Dispose。
如果您正在使用数据集,请执行相同操作。
这是否会在高负载时间发生?如果是这样,您可能需要调查Crystal Reports的许可和性能限制。
答案 1 :(得分:0)
您的数据库已打开,在您的项目中,转到数据库视图,单击数据库,单击刷新,然后单击关闭连接。在此之后,您应该能够运行此代码。
答案 2 :(得分:0)
我们通过在ExportToStream周围添加重试来“解决”我们的ASP.NET MVC应用程序中的问题。我们尝试了所有其他建议但没有任何效果。
using (var memoryStream = new MemoryStream())
using (var stream = RetryHelper.Retry(() => reportDoc.ExportToStream(ExportFormatType.PortableDocFormat)))
{
stream.CopyTo(memoryStream);
fileInfo.Data = memoryStream.ToArray();
}
...其中Retry()方法是......
public static T Retry<T>(Func<T> action)
{
bool success = false;
int count = 0;
T response = default(T);
while (!success)
{
try
{
count++;
response = action();
success = true;
}
catch (Exception ex)
{
//only try 10 times with increasing sleeps
if (count >= 10)
{
throw;
}
string message = ex.Message;
int sleepTimeInMilliSeconds = 100 * count * count;//100ms, 400, 900, 1600 ......
Log.Debug(string.Format("Failed. Attempt {0}. Error={1}. Sleeping for {2}ms", count, message, sleepTimeInMilliSeconds), ex);
Thread.Sleep(sleepTimeInMilliSeconds);
}
}
return response;
}
Rant - 我不是一个很棒的CR粉丝。我们正在从CR转向基于phantomjs的pdf解决方案。
答案 3 :(得分:0)
是否使用reportDocument.Load方法打开报告文件。如果是这样尝试使用OpenReportMethod.OpenReportByTempCopy选项,那么它看起来像这样
reportDocument.Load(file, OpenReportMethod.OpenReportByTempCopy);