SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
Hi again.
For time to time we get into a situation where the entire GUI freezes. When investigating the application dump, the freeze is found to be located in the constructor of BitmapContext, or rather inside a .Net-method called as a result of the constructor. The area of interest seems to be the use of the BackBuffer property of WriteableBitmap. This in turn ends up waiting for an event inside AcquireBackBuffer (the ManualResetEvent variable is called _copyCompletedEvent). On MSDN Microsoft states that one should call the Lock- and Unlock-methods when updating the back buffer ( http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.backbuffer(v=vs.110).aspx). I seems like this is not always the case in the SciChart source code, but I’m unable to determine if this can cause the lock.
Call stack:
mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) + 0x2b bytes
mscorlib.dll!System.Threading.WaitHandle.WaitOne(System.TimeSpan timeout, bool exitContext) + 0x6e bytes
PresentationCore.dll!System.Windows.Media.Imaging.WriteableBitmap.AcquireBackBuffer(System.TimeSpan timeout, bool waitForCopy) + 0x37 bytes
> PresentationCore.dll!System.Windows.Media.Imaging.WriteableBitmap.TryLock(System.Windows.Duration timeout) + 0x10c bytes
Abt.Controls.SciChart.Wpf.2.2.dll!System.Windows.Media.Imaging.BitmapContext.BitmapContext(System.Windows.Media.Imaging.WriteableBitmap c1505829363987065354c2524c41152e4) + 0xa6 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!A.c6e54b260f3e614b850e733a2116b4878.c6e54b260f3e614b850e733a2116b4878(System.Windows.Controls.Image c9f773d96fd8c18abf23cfdb63f49fe85, System.Windows.Media.Imaging.WriteableBitmap ce748be01e2f961df40736b3a402f6c8a, Abt.Controls.SciChart.Rendering.Common.SizeF cacf0a4a95d1143f0c11e20d4508e7132, A.c1712c9b21919ce890684525c1002f4a7 c10fe853bbcfc02fab8756c021ff9007b) + 0xb7 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!A.ccd89db9dd1768b91d35b2d2bb15f2f07.cb398c793fba70ab574d5eb126a856bcf(System.Windows.Media.Imaging.WriteableBitmap c1505829363987065354c2524c41152e4, System.Windows.Controls.Image c9f773d96fd8c18abf23cfdb63f49fe85, A.c1712c9b21919ce890684525c1002f4a7 c10fe853bbcfc02fab8756c021ff9007b) + 0x61 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Visuals.Axes.AxisBase.OnDraw(Abt.Controls.SciChart.Rendering.Common.IRenderContext2D renderContext, Abt.Controls.SciChart.Visuals.RenderableSeries.IRenderPassData renderPassData) + 0x82 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!A.cda144392e546b245ef5bb1ee71f22b3a.c6a7d2b5be124728330bbf562594a9bb9(Abt.Controls.SciChart.Visuals.ISciChartSurface c17037e8328cd0abc02d2a6957dfa450c, Abt.Controls.SciChart.RenderPassInfo c16b8d70d2b6ecad8f9fca7ac3f5177b8, Abt.Controls.SciChart.Rendering.Common.IRenderContext2D c41db0419b661c8ac05a2aa6a1ea66092) + 0x66 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!A.cda144392e546b245ef5bb1ee71f22b3a.RenderLoop(Abt.Controls.SciChart.Rendering.Common.IRenderContext2D renderContext) + 0x155 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Visuals.SciChartSurface.ca065c0b671221e0e603d0e9bf2792494() + 0x3e bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Visuals.SciChartSurface.cc0485eb45a8d4f00283729754056deb8() + 0x3e bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Visuals.SciChartSurface.OnRenderSurfaceDraw(object sender, Abt.Controls.SciChart.Rendering.Common.DrawEventArgs e) + 0x84 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Rendering.Common.RenderSurfaceBase.OnDraw() + 0x92 bytes
Abt.Controls.SciChart.Wpf.2.2.dll!Abt.Controls.SciChart.Rendering.Common.RenderSurfaceBase.OnCompositionTargetRendering(object sender, System.EventArgs e) + 0x1c bytes
Have you had any experience with this?
Best regards,
Bjørn Terje Svennes
Hi Bjorn,
Yes, we are calling lock there. However that will only block if called on more than one thread at one time. In SciChart codebase we only ever call BitmapContext constructors on the UI thread.
So do you think that there is a mismatch between Lock/Unlock calls for the Bitmap? Or we need to call Lock/Unlock every time?
I can review this code. It’s quite deep in the guts of SciChart and so far seems to have worked, but you never know …
Andrew
The UI thread can block when the render thread acquires a lock on the back buffer to copy it forward to the front buffer. If the latency from this block is too long, use the TryLock method to wait for a short time and then unblock the UI thread to perform other tasks while the back buffer is locked.Do you have any ideas on for how long the lock is kept in BitmapContext? I've never used WriteableBitmap and I'm a bit on thin ice now. But from what you are saying, you had an issue every 1000 frames or so. This fits with our situation too. It happens rarely, but when it does the entire application locks and needs to be terminated from TaskManager. This is not very pleasant for the customers. Bjørn Terje
Please login first to submit.