Drucken eines lokalen Berichts ohne Vorschau - Streamgröße überschritten oder In GDI + C # ist ein allgemeiner Fehler aufgetreten

8

Ich verwende diesen Artikel, um meine rdlc direkt auf den Drucker zu drucken, aber wenn ich es versuche um Metafile object zu erstellen, indem stream übergeben wird, gibt es einen Fehler. ( Ein allgemeiner Fehler ist in GDI + aufgetreten )

Code:

%Vor%

Es gibt mir einen Fehler, wenn die Stream-Größe oder rdlc statischen Inhalt ist mehr.

Mein Dataset, mit dem ich einen Stream erstellen kann, ist:

Ich weiß nicht, ob der statische Inhalt die Stream-Größe nicht beeinflussen soll oder nicht, aber es gibt mir keinen Fehler, wenn ich Inhalte aus rdlc entferne, aber wenn ich hinzufüge, dass es erneut einen Fehler gibt ( Ein generischer Fehler ist aufgetreten in GDI + )

    
3 rules 29.07.2017, 13:04
quelle

2 Antworten

1

An meinem Ende mit den gleichen Funktionen wie Sie verwenden und das gleiche Problem bekommen weiß nicht, warum ich die angegebene Funktion verwenden, aber es läuft an meinem Ende, so dass diese Funktion Ihr Problem lösen kann:

%Vor%     
Mahavirsinh Padhiyar 01.03.2018, 09:01
quelle
3

Ein generischer Fehler Ausnahme ist eine ziemlich miese Ausnahme zu diagnostizieren. Es vermittelt wenig Informationen über "es hat nicht funktioniert". Die Ausnahme wird immer dann ausgelöst, wenn die Graphics-Klasse Probleme beim Verwenden von Zeichnungsobjekten oder beim Rendern der Zeichnungsbefehle für den zugrunde liegenden Gerätekontext hat. Es gibt einen klaren und offensichtlichen Grund dafür in diesem Code und von den Dingen, die Sie getan haben, um es zu beheben: das Programm hat nicht genug Speicher .

Die Graphics-Klasse behandelt den zugrundeliegenden Gerätekontext als nicht verwaltete Ressource, der Hauptgrund, warum Sie nicht die offensichtlichere OutOfMemoryException erhalten. Es ist normalerweise, wie wenn Sie es verwenden, um auf dem Bildschirm oder einem Drucker zu rendern, nur nicht in diesem Fall, da es auf einem MemoryStream rendert. Einige Chancen, dass Sie im VS-Ausgabefenster die Benachrichtigung über die erste Chance sehen können. Das Hinzufügen der Spalte "Commit Size" im Task-Manager kann eine zusätzliche Diagnose bereitstellen. Wenn der Fehler nördlich eines Gigabytes angezeigt wird, tritt ein Problem auf.

Besonders bemerkenswert an diesem Code ist, dass das Programm immer mit dieser Ausnahme fehlschlägt. Geben Sie ihm einen Bericht mit zu vielen Seiten oder einer Datentabelle mit zu vielen Datensätzen, und es ist zum Scheitern verurteilt. Es wird unweigerlich immer zu viel Speicher benötigen, um die Metadatei-Datensätze in den Speicherströmen zu speichern. Das einzige, was Sie tun können, ist, das Programm speichereffizienter zu machen, damit es den Produktionsanforderungen gerecht wird. Viele Möglichkeiten hier.

Erste Beobachtung ist, dass Sie etwas Schlamperei aus dem MSDN-Codebeispiel geerbt haben. Was allgemein üblich ist und etwas, vor dem man sich hüten sollte, solche Beispiele konzentrieren sich auf die Demonstration von Codiertechniken. Der kugelsichere Code steht der Mission im Weg, ungetestet und als Übung dem Leser überlassen. Bemerkenswert ist, dass es die Notwendigkeit, Dispose () zu viel zu ignorieren, ignoriert. Die zur Verfügung gestellte Dispose () -Methode führt eigentlich gar nichts aus, ein Speicher-Stream wird nur als unlesbar markiert. Was es nicht tut, ist, die Objekte Metafile, LocalReport und PrintDocument ordnungsgemäß zu entsorgen. Verwenden Sie die using -Anweisung, um diese Auslassungen zu korrigieren.

Zweite Beobachtung ist, dass das Hinzufügen der CreateStream () -Methode eine enorme Verschwendung ist. Auch die schlechte Art der Verschwendung, es ist sehr grob auf dem Large Object Heap. Es ist nicht notwendig, die DataTable Copy () zu kopieren, der Bericht schreibt nicht darauf. Es besteht keine Notwendigkeit, den MemoryStream in ein Array zu konvertieren und einen MemoryStream erneut aus dem Array zu erstellen, der erste MemoryStream ist bereits so wie er ist. Verwenden Sie nicht mit , setzen Sie seine Position auf 0. Das ist wahrscheinlich gut genug, um das Problem zu lösen.

Wenn Sie immer noch Probleme haben, sollten Sie einen FileStream anstatt eines MemoryStream verwenden. Es wird genauso effizient sein, das OS stellt sicher, dass es die einzige zusätzliche Last ist, einen Namen für die Datei auszuwählen. Kein echtes Problem hier, verwenden Sie Path.GetTempFileName (). Beachten Sie, dass die Dispose () -Methode jetzt nützlich und notwendig wird. Sie sollten die Datei auch wieder löschen. Oder besser, verwenden Sie die Option FileOptions.DeleteOnClose, wenn Sie die Datei automatisch öffnen.

Und zu guter Letzt möchten Sie die Vorteile des Betriebssystems nutzen, moderne Maschinen können Terabytes an Adressraum bereitstellen und die LOH-Fragmentierung ist nie ein Problem. Projekt & gt; Eigenschaften & gt; Erstellen Registerkarte & gt; Deaktivieren Sie das Kontrollkästchen "32-Bit bevorzugen". Wiederholen Sie dies für die Release-Konfiguration. Sie bevorzugen es nie, wenn Sie nicht genügend Arbeitsspeicherprobleme haben.

    
Hans Passant 16.08.2017 12:08
quelle

Tags und Links