Visual Studio 2010 Productivity Power Tools crashing when add-in calls Application.DoEvents

I had three bug reports from customers of my MZ-Tools add-in for Visual Studio 2010 with a “System.NullReferenceException: Object reference not set to an instance of an object.” that happened “when closing Visual Studio”. The stack trace is something like this:

System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.VisualStudio.Text.Editor.Implementation.DefaultScrollMap.TranslatePosition(SnapshotPoint bufferPosition)
at Microsoft.VisualStudio.Text.Editor.Implementation.DefaultScrollMap.GetCoordinateAtBufferPosition(SnapshotPoint bufferPosition)
at Microsoft.PowerTools.OverviewMargin.Implementation.OverviewMargin.SimpleScrollBar.GetYCoordinateOfBufferPosition(SnapshotPoint bufferPosition)
at Microsoft.PowerTools.CaretMargin.CaretMarginElement.InvalidateIfChanged(Boolean highlightsChanged)
at Microsoft.PowerTools.CaretMargin.CaretMarginElement.<UpdateMarginMatches>b__1(Object )
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.ExecuteCodeWithGuaranteedCleanup(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.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 uReason, Int32 pvLoopData)
at System.Windows.Forms.ComponentManagerProxy.System.Windows.Forms.UnsafeNativeMethods.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.DoEvents()


And indeed my add-in calls Application.DoEvents() in the event handler that sets to get notified when a solution is closed (that’s why the exception can happen “when closing Visual Studio”). I patched my add-in to ignore that exception, but the other day I got that exception too when calling DoEvents in other parts of the add-in, so it seems that any call to Application.DoEvents() can cause that exception in the Visual Studio 2010 Productivity Power Tools. I am using the latest version 10.0.20318.14 at the time of this writing.