1
votes

I have a WinForms Application (.net 4.0, x86) with Crystal Reports (13.0.15). I want to print multiple documents using Crystal Reports (without seeing them on Report Viewer - directly on printer).

foreach (var document in documents )
{
  ReportDocument report=GenerateReport(document.id);
  report.PrintToPrinter(printerSettings, pageSettings, false);
}

Everytime it prints 48 reports and on 49th print I've got exception System.ComponentModel.Win32Exception The handle is invalid Void OnStartPrint(System.Drawing.Printing.PrintDocument, System.Drawing.Printing.PrintEventArgs)

I tried another set of documents but I still have exception on 49 print.

I tried to change PrintJobLimit to over 9000 but it doesn't help.

Next I tried to dispose report after print:

foreach (var document in documents )
{
  using (ReportDocument report=GenerateReport(document.id))
  { 
    report.PrintToPrinter(printerSettings, pageSettings, false);
  }
}

But now program crashes before print 28th report and I cannot catch exception (program stop working). Only in Event Viewer is information about Application Error (Faulting module name: ntdll.dll). I tried different things (and combination of them):

    report.Close();

    report.Dispose();

    report=null;

even GC.Collect() after print but it still doesn't work. Anybody has a solution?

1

1 Answers

0
votes

It seems like when report.PrintToPrinter returned, the underlying operation sometimes went on. You need to keep reportDocument alive for a few more time, instead of let it go out of scope and GC collection kick in.

My solution is to put them into a delayed queue and Close them later, something like:

foreach (var document in documents )
{
    ReportDocument report = GenerateReport(document.id);
  
    report.PrintToPrinter(printerSettings, pageSettings, false);
    Task.Run(async () => {
        // keep report alive for extra 60 secs
        await Task.Delay(60 * 1000);
        report.Close();
        report.Dispose();
    })
  
}