Notice (2018-05-24): bugzilla.xamarin.com is now in
Please join us on
Visual Studio Developer Community and in the
Mono organizations on
GitHub to continue tracking issues. Bugzilla will remain
available for reference in read-only mode. We will continue to work
on open Bugzilla bugs, copy them to the new locations
as needed for follow-up, and add the new items under Related
Our sincere thanks to everyone who has contributed on this bug
tracker over the years. Thanks also for your understanding as we
make these adjustments and improvements for the future.
Please create a new report on
Developer Community or GitHub with
your current version information, steps to reproduce, and relevant error
messages or log files if you are hitting an issue that looks similar to
this resolved bug and you do not yet see a matching new report.
Created attachment 671 [details]
I have written a PDF viewer that has a UISlider. Sliding it generates previews of the target page. The preview is rendered in a separate thread.
On iPad 1 creating and cancelling only one thread makes the device unusable. CPU is at 100%. From Instruments I can see that it is stuck in the Garbage Collector.
I is of course possible that I am doing something I should not do, but I am not aware what that would be.
Here's the method that gets called whenever UISlider changes it value (note that chaing value means dragging it quite a bit), so it's not that I cerate and destroy millions of threads.
Any ideas why this drives GC nuts?
private void RenderScrollPreviewImages (int iPage)
if(this.oScrollSliderPreview == null)
SizeF oSize = new SizeF(150, 200);
RectangleF oFrame = new RectangleF(new PointF (this.View.Bounds.Width - oSize.Width - 50, this.GetScrollSliderOffset (oSize)), oSize);
this.oScrollSliderPreview = new UIView(oFrame);
this.oScrollSliderPreview.UserInteractionEnabled = false;
this.oScrollSliderPreview.Layer.BorderWidth = 2.0f;
this.oScrollSliderPreview.Layer.BorderColor = UIColor.Black.CGColor;
this.oScrollSliderPreview.BackgroundColor = UIColor.White;
UIActivityIndicatorView oIndicator = new UIActivityIndicatorView(UIActivityIndicatorViewStyle.Gray);
oIndicator.Center = new PointF(this.oScrollSliderPreview.Bounds.Width/2, this.oScrollSliderPreview.Bounds.Height/2);
if(this.oScrollSliderPreview.Subviews.Length > 0)
foreach(UIView oSubview in this.oScrollSliderPreview.Subviews)
if(!(oSubview is UIActivityIndicatorView))
if(this.oRenderScrollPreviewImagesThread != null)
this.oRenderScrollPreviewImagesThread = new Thread (delegate()
using (var oPool = new NSAutoreleasePool())
UIImageView oImgView = PdfViewerHelpers.GetLowResPagePreview (this.oPdfDoc.GetPage (iPage), new RectangleF (0, 0, 150, 200));
if(this.oScrollSliderPreview != null)
oImgView.Center = new PointF(this.oScrollSliderPreview.Bounds.Width/2, this.oScrollSliderPreview.Bounds.Height/2);
Maybe not clear enough: the CPU remains at 100% forever. It will never catch up again until I kill the app.
I get this with DEBUG and RELEASE, with sGen and without.
The code responsible fro the issue in the end is the line:
UIImageView oImgView =
PdfViewerHelpers.GetLowResPagePreview (this.oPdfDoc.GetPage (iPage), new
RectangleF (0, 0, 150, 200));
It is creating an image view preview of a PDF page. Anything obviously fishy with that code?
internal static UIImageView GetLowResPagePreview (CGPDFPage oPdfPage, RectangleF oTargetRect)
RectangleF oPdfPageRect = oPdfPage.GetBoxRect (CGPDFBox.Media);
// If preview is requested for the PDF index view, render a smaller version.
float fAspectScale = 1.0f;
fAspectScale = GetAspectZoomFactor (oTargetRect.Size, oPdfPageRect.Size, false);
// Resize the PDF page so that it fits the target rectangle.
oPdfPageRect = new RectangleF (new PointF (0, 0), GetFittingBox (oTargetRect.Size, oPdfPageRect.Size));
// Create a low res image representation of the PDF page to display before the TiledPDFView
// renders its content.
CGContext oContext = UIGraphics.GetCurrentContext ();
// First fill the background with white.
oContext.SetFillColor (1.0f, 1.0f, 1.0f, 1.0f);
// Flip the context so that the PDF page is rendered right side up.
oContext.TranslateCTM (0.0f, oPdfPageRect.Size.Height);
oContext.ScaleCTM (1.0f, -1.0f);
// Scale the context so that the PDF page is rendered
// at the correct size for the zoom level.
oContext.ScaleCTM (fAspectScale, fAspectScale);
UIImage oBackgroundImage = UIGraphics.GetImageFromCurrentImageContext ();
UIImageView oBackgroundImageView = new UIImageView (oBackgroundImage);
oBackgroundImageView.Frame = new RectangleF (new PointF (0, 0), oPdfPageRect.Size);
oBackgroundImageView.ContentMode = UIViewContentMode.ScaleToFill;
oBackgroundImageView.AutoresizingMask = UIViewAutoresizing.None;
It's not the GC thread, it's your thread that's stuck (the fact that there's a GC_start_routine method at the top of the stack trace doesn't mean that it's the GC thread, just that it's a thread the GC knows about).
Second maybe you could find out which exception is getting thrown? That might help you figure out what's going on.
The only fishy bit that I see in this code is the use of Thread.Abort which is a heavy-handed approach that can leave the system in an inconsistent state.
It is best if you use Thread.Interrupt as it is a lot milder and will properly unwind code and release resources.
I cannot reproduce anymore.