title: VSIX - Deadlock on XmlEditingScope.Complete()
body: <p>We are using the classes in the Microsoft.VisualStudio.XmlEditor namespace (<a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.aspx" rel="noreferrer">https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.aspx</a>) to modify an xml document in an Visual Studio Extension.</p>
  
  <p>For some reason a deadlock occurs after calling the <a href="https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.xmleditingscope.aspx" rel="noreferrer">XmlEditingScope.Complete()</a> method. In the statusbar of Visual Studio, we see the message "Waiting for parse to complete..."</p>
  
  <p>This is the stack trace of the deadlocked UI thread:
  </p>
  
  <pre><code>WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)   
  mscorlib.dll!System.Threading.SynchronizationContext.InvokeWaitMethodHelper(System.Threading.SynchronizationContext syncContext, System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)     
  [Native to Managed Transition]   
  [Managed to Native Transition]   
  mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext)   
  mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext)  
  Microsoft.VisualStudio.Package.LanguageService.14.0.dll!Microsoft.VisualStudio.Package.LanguageService.ParseWaitHandle.WaitOne(int millisecondsTimeout, bool exitContext)    
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.XmlLanguageService.WaitForParse(System.IAsyncResult result, Microsoft.XmlEditor.StatusBarIndicator indicator)    
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.XmlLanguageService.WaitForParse()    
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.XmlParserLock.XmlParserLock(Microsoft.XmlEditor.XmlLanguageService service)  
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.Transaction.PushToEditorTreeAndBuffer()  
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.Transaction.Complete()   
  XmlEditingScope.Complete() Line 64
  </code></pre>
  
  
  
  <p>And the Visual Studio parse thread:</p>
  
  <pre><code>mscorlib.dll!System.Threading.WaitHandle.InternalWaitOne(System.Runtime.InteropServices.SafeHandle waitableSafeHandle, long millisecondsTimeout, bool hasThreadAffinity, bool exitContext) + 0x21 bytes  
  mscorlib.dll!System.Threading.WaitHandle.WaitOne(int millisecondsTimeout, bool exitContext) + 0x28 bytes     
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.LockManager.Lock(object resource, Microsoft.XmlEditor.LockMode mode, Microsoft.XmlEditor.Transaction txId) + 0x14c bytes     
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.TransactionManager.BeginParseSourceTransaction(Microsoft.XmlEditor.XmlSource src, Microsoft.XmlEditor.Transaction parent) + 0x9f bytes   
  Microsoft.XmlEditor.dll!Microsoft.XmlEditor.XmlLanguageService.ParseSource(Microsoft.VisualStudio.Package.ParseRequest req) + 0x17d bytes    
  Microsoft.VisualStudio.Package.LanguageService.14.0.dll!Microsoft.VisualStudio.Package.LanguageService.ParseRequest(Microsoft.VisualStudio.Package.ParseRequest req) + 0x75 bytes    
  Microsoft.VisualStudio.Package.LanguageService.14.0.dll!Microsoft.VisualStudio.Package.LanguageService.ParseThread() + 0x140 bytes   
  mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x70 bytes    
  mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes   
  mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes   
  mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes     
  mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes    
  [Native to Managed Transition]  
  </code></pre>
  
  <p>It's not easy to show all relevant code here, but basically it's just the following code that is executed after a change in a WPF DataGrid control (IEditableObject.EndEdit in ViewModel):</p>
  
  <pre><code>using (var s = store.BeginEditingScope("Test", null))
  {
         apply changes in xmlModel.Document... 
  
         s.Complete();
  }
  </code></pre>
  
  <p>What can I do to prevent this deadlock from happening. Do I need to lock on something before applying the changes? What else could I'm doing wrong?</p>