Wir verwenden die Klassen im Namespace Microsoft.VisualStudio.XmlEditor (https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.xmleditor.aspx), um ein XML-Dokument in einer Visual Studio-Erweiterung zu ändern.VSIX - Deadlock auf XmlEditingScope.Complete()
Aus irgendeinem Grund tritt nach dem Aufruf der Methode XmlEditingScope.Complete() ein Deadlock auf. In der Statusleiste von Visual Studio, sehen wir die Meldung "Waiting for Parsing zu vervollständigen ..."
Dies ist der Stack-Trace des Deadlock UI-Thread:
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
Und das Visual Studio parsen thread:
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]
es ist nicht einfach hier alle relevanten Codes zu erhalten, aber im Grunde ist es nur der folgende Code, der nach einer Änderung in einem WPF-Datagrid-Steuerelement (IEditableObject.EndEdit ausgeführt wird in ViewModel):
using (var s = store.BeginEditingScope("Test", null))
{
apply changes in xmlModel.Document...
s.Complete();
}
Was kann ich tun, um dieses Deadlock zu verhindern. Muss ich etwas sperren, bevor ich die Änderungen anwende? Was könnte ich sonst falsch machen?
Evk, danke für deine Antwort. Ich habe versucht, XmlEditingScope auf einem Hintergrundthread auszuführen, aber dann erhalte ich eine System.AccessViolationException. bei Microsoft.VisualStudio.Shell.Interop.IVsQueryEditQuerySave2.QueryEditFiles (UInt32 rgfQueryEdit, Int32 cFiles, String [] rgpszMkDocuments, UInt32 [] rgrgf, VSQEQS_FILE_ATTRIBUTE_DATA [] rgFileInfo, UInt32 & pfEditVerdict, UInt32 & prgfMoreInfo) bei Microsoft.XmlEditor.Transaction.CanEditFilesInTransaction() bei Microsoft.XmlEditor.Transaction.PushToEditorTreeAndBuffer() bei Microsoft.XmlEditor.Transaction.Complete() – TWT
Nun schwer, mehr Ratschläge ohne zusätzliche Informationen zu geben. Aber zumindest ist es jetzt nicht festgefahren :) Und was ist, wenn Sie es zum UI-Thread aber über Dispatcher.BeginInvoke (so asynchron) versenden? – Evk