/// <summary> /// Invalidates this instance. /// </summary> public void Invalidate() { if (this.rendered) { return; } this.rendered = true; this.OnPropertyChanged("Width"); this.OnPropertyChanged("Height"); this.OnPropertyChanged("ImageSource"); int desiredWidth = Width; int desiredHeight = Height; if (this.tokenSource != null) { this.tokenSource.Cancel(); } this.tokenSource = new CancellationTokenSource(); this.tokenSource.Token.ThrowIfCancellationRequested(); Dispatcher dispatcher = Dispatcher.CurrentDispatcher; this.image = new byte[desiredWidth * desiredHeight * 4]; RenderingSettings renderingSettings = new RenderingSettings(); renderingSettings.DrawText = this.DrawText; renderingSettings.DrawImages = this.DrawImages; renderingSettings.DrawPaths = this.DrawPaths; renderingSettings.DrawAnotations = this.DrawAnnotations; renderingSettings.AnnotationRenderingSettings = new RenderingSettings(); renderingSettings.AnnotationRenderingSettings.DrawText = this.DrawAnnotationsText; // Uncomment to not draw annotations // renderingSettings.DrawAnotations = false; Task renderingTask = new Task(() => this.page.RenderAsBytes(desiredWidth, desiredHeight, this.image, renderingSettings)); this.task = Task.Factory.StartNew( () => { renderingTask.Start(); while (!(renderingTask.IsCompleted || renderingTask.IsCanceled || renderingTask.IsFaulted)) { if (tokenSource.IsCancellationRequested) { renderingSettings.CancelRendering(); this.rendered = false; this.task = null; this.source = null; this.tokenSource = null; this.image = null; break; } renderingTask.Wait(1000); dispatcher.Invoke(DispatcherPriority.DataBind, new Action(() => { source = BitmapSource.Create(this.Width, this.Height, 72, 72, PixelFormats.Bgra32, null, image, 4 * this.Width); this.OnPropertyChanged("ImageSource"); })); } this.image = null; dispatcher.Invoke(DispatcherPriority.Background, new Action(() => { if (this.source != null) { this.source.Freeze(); } })); GC.Collect(); }, this.tokenSource.Token); }