2012-01-30 55 views
1

FixedDocumentレポートを毎月印刷するように作成しました。それはページの約半分が約200kbのjpeg画像であることで、長さが約350ページ平均します。このレポートはDocumentViewerにうまく表示されますが、印刷しようとすると問題が発生します。WPF大きなレポートを印刷するとOutOfMemoryExceptionが発生する

私はちょうどヶ月のデータなどの最初の3分の1を試してみて、印刷する場合

DocumentViewer1.Print() 

を使用。 120ページ、それは正常に動作します。 しかし、私は一ヶ月しようとした場合、第160ページ程度で、私は次のエラー

System.OutOfMemoryException: Insufficient memory to continue the execution 
of the program. 
    at System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(Int32Rect 
sourceRect, IntPtr buffer, Int32 bufferSize, Int32 stride) 
    at System.Windows.Media.Imaging.BitmapSource.CriticalCopyPixels(Int32Rect 
sourceRect, Array pixels, Int32 stride, Int32 offset) 
    at Microsoft.Internal.GDIExporter.CGDIBitmap.Load(BitmapSource pBitmap, 
Byte[] buffer, PixelFormat LoadFormat) 
    at 
Microsoft.Internal.GDIExporter.CGDIRenderTarget.DrawBitmap(BitmapSource 
pImage, Byte[] buffer, Rect rectDest) 
    at Microsoft.Internal.GDIExporter.CGDIRenderTarget.DrawImage(BitmapSource 
source, Byte[] buffer, Rect rect) 
    at 
Microsoft.Internal.AlphaFlattener.BrushProxyDecomposer.Microsoft.Internal.Al 
phaFlattener.IProxyDrawingContext.DrawImage(ImageProxy image, Rect dest, 
Geometry clip, Matrix trans) 
    at 
Microsoft.Internal.AlphaFlattener.PrimitiveRenderer.RenderImage(ImageProxy 
image, Rect dest, Geometry bounds, Boolean clipToBounds, Int32 start, Matrix 
trans, String desp) 
    at 
Microsoft.Internal.AlphaFlattener.PrimitiveRenderer.RenderImage(ImageProxy 
image, Rect dest, Geometry clip, Matrix trans, String desp) 
    at Microsoft.Internal.AlphaFlattener.Flattener.AlphaRender(Primitive 
primitive, List`1 overlapping, Int32 overlapHasTransparency, Boolean 
disjoint, String desp) 
    at 
Microsoft.Internal.AlphaFlattener.Flattener.AlphaFlatten(IProxyDrawingContex 
t dc, Boolean disjoint) 
    at Microsoft.Internal.AlphaFlattener.Flattener.Convert(Primitive tree, 
ILegacyDevice dc, Double width, Double height, Double dpix, Double dpiy, 
Nullable`1 quality) 
    at Microsoft.Internal.AlphaFlattener.MetroDevice0.FlushPage(ILegacyDevice 
sink, Double width, Double height, Nullable`1 outputQuality) 
    at Microsoft.Internal.AlphaFlattener.MetroToGdiConverter.FlushPage() 
    at 
System.Windows.Xps.Serialization.NgcSerializationManagerAsync.EndPage() 
    at 
System.Windows.Xps.Serialization.NgcFixedPageSerializerAsync.EndPersistObjec 
tData(Boolean isManualStartDoc) 
    at 
System.Windows.Xps.Serialization.NgcFixedPageSerializerAsync.AsyncOperation(
NGCSerializerContext context) 
    at 
System.Windows.Xps.Serialization.NgcSerializationManagerAsync.InvokeSaveAsXa 
mlWorkItem(Object arg) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate 
callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object 
source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.DispatcherOperation.InvokeImpl() 
    at 
System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object 
state) 
    at System.Threading.ExecutionContext.runTryCode(Object userData) 
    at 
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedClea 
nup(TryCode code, CleanupCode backoutCode, Object userData) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext 
executionContext, ContextCallback callback, Object state) 
    at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean 
ignoreSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state) 
    at System.Windows.Threading.DispatcherOperation.Invoke() 
    at System.Windows.Threading.Dispatcher.ProcessQueue() 
    at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 
msg, IntPtr wParam, IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, 
IntPtr lParam, Boolean& handled) 
    at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) 
    at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate 
callback, Object args, Int32 numArgs) 
    at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object 
source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) 
    at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority 
priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) 
    at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr 
wParam, IntPtr lParam) 
    at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
    at 
System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.Unsaf 
eNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, 
Int32 reason, Int32 pvLoopData) 
    at 
System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 
reason, ApplicationContext context) 
    at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 
reason, ApplicationContext context) 
    at System.Windows.Forms.Application.Run(ApplicationContext context) 
    at 
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun(
) 
    at 
Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoAppl 
icationModel() 

を取得し、私はその後、私はほんの少しの30ページにドキュメントを分割することによって一度に30ページを印刷して、それの裏をかくしようと思いました文書を使用して:

Dim dlg = New PrintDialog() 


    If dlg.ShowDialog() = True Then 

     Dim PageCounter As Int32 = 0 
     Dim ListOfDocs As New List(Of FixedDocument) 
     Dim CurrentFixedDoc As New FixedDocument 


     For Each FixedSizePag As FixedPage In PrintListOfPages 

      Dim FixedSizedPageConten As PageContent = New PageContent 

      CType(FixedSizedPageConten, IAddChild).AddChild(FixedSizePag) 
      CurrentFixedDoc.Pages.Add(FixedSizedPageConten) 

      PageCounter = PageCounter + 1 

      If PageCounter >= 30 Then 
       ListOfDocs.Add(CurrentFixedDoc) 
       PageCounter = 0 
       CurrentFixedDoc = New FixedDocument 
      End If 

     Next 

     If CurrentFixedDoc.Pages.Count > 0 Then 
      ListOfDocs.Add(CurrentFixedDoc) 
     End If 

     For Each docum In ListOfDocs 
      dlg.PrintDocument(docum.DocumentPaginator, "Testing - Part " & (ListOfDocs.IndexOf(docum) + 1) & " of " & ListOfDocs.Count) 
     Next 

    End If 

しかし、これはまさに同じエラーを引き起こしました。私は中点から終わりに向かって100ページを印刷しようとしましたが、それは動作します。特定のイメージではなく、ページの量でなければなりません。イメージは1つのソースからすべてjpegです(最大サイズ400kb)。私は

Start = 96Mb 
    30 pages = 367Mb 
    60 pages = 588Mb 
    90 pages = 825Mb 
    120 pages = 1003Mb 
    150 pages = 1238Mb 

が、私は本当のプリンタでテストされ、XPSまし1281Mb

で次のバッチにクラッシュ参照時に30ページを印刷する時に使用されているメモリの量を見て

Windowsプリンタ。私はこれらのメモリ値を書き留めたところで、各セクションが完全にスプールされて印刷されるまで待っていました。

なぜ私は別々の個別のドキュメントに分割しているときに、このように構築するのか理解できません。私は何かを処分する必要がありますが、私は何が分からないのですか?

+0

私も(GC.Collectを試してみた) GC.WaitForPendingFinalizers()まだ同じエラーを生成します。何か案は? – SpeedBird527

+0

似たような問題があります...回避策を見つけましたか? – Mike

答えて

0

ファイルごとに10ページ(ファイルごとにFixedDocument)を生成し、これらのファイルを1つにマージする必要があります(FixedDocumentSequenceがあります)。次に、このFixedDocumentSequenceに印刷します。私は、このソリューションはあまりメモリを消費しないと確信しています。

System.Windows.Xps.XpsDocumentWriter.Write(System.Windows.Documents.FixedDocumentSequence FixedDocumentSequenceに)

関連する問題