Crystal Reports - 进程无法访问该文件,因为该文件正由另一个进程使用

时间:2014-10-07 00:17:38

标签: crystal-reports

将水晶报表导出为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)

如何解决这个问题?

4 个答案:

答案 0 :(得分:2)

主要问题是你对水晶医生的记忆。因此,每次导出后,您必须清理对象,清除缓存和GAC。

http://www.brianstevenson.com/blog/solution-the-process-cannot-access-the-file-filename-because-it-is-being-used-by-another-process

首先检查上面的链接,我搜索并找到一个如下(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);