How does RegisterService / GetService work internally?

SyntaxEditor for WPF Forum

Posted 9 months ago by Reinhard Gruber
Version: 18.1.0672
Avatar

Hi,

we are working with SyntaxEditor and have implemented our own Language called BDL. Everything works fine except from time to time our UI-test-machine delivers a crash dump with the following exception:

Collection was modified; enumeration operation may not execute.
    at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.KeyCollection.Enumerator.MoveNext()
   at ActiproSoftware.Text.Implementation.CodeDocument.GetServices[#Mnc](ISyntaxLanguage #6Bf)
   at ActiproSoftware.Text.Implementation.CodeDocument.OnParseDataChanged(ParseDataPropertyChangedEventArgs e)
   at ActiproSoftware.Text.Implementation.CodeDocument.set_ParseData(IParseData value)
   at ActiproSoftware.Text.Implementation.CodeDocument.NotifyParseComplete(IParseRequest request, IParseData result)
   at ActiproSoftware.Text.Implementation.CodeDocument.#bGc(IParseRequest #FMc, IParseData #GF)
   at ActiproSoftware.Text.Parsing.Implementation.ThreadedParseRequestDispatcher.#0Yc.#nXc(IParseRequest #FMc)
   at ActiproSoftware.Text.Parsing.Implementation.ThreadedParseRequestDispatcher.#0Yc.#56c()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

But we never register a service with the Document, but only with the language. In the constructor of our BdlLanguage-class a lot of RegisterService-calls are done. Then we build up our ViewModel, that contains an instance of CodeDocument, where the BdlLanguage instance is assigned to the CodeDocument.Language property and where also 2 more Services are registered. Finally the ViewModel is bound to the UI control. There the SyntaxEditor control has an event-handler OnDocumentChanged where a UI-related service (CustomSquiggleTagQuickInfoProvider) is registered on the new Documents language.

Is this bad design? Is it intended to register all the services within the constructor of the language class only? Is there any chance to lock the collection of registered services to avoid this exception? Except for the ui related service all other services are exactly the same for all document instances. Is it possible to have some static shared Services-collection that is registered once at program start to avoid this exception?

[Modified 9 months ago]

Comments (1)

Answer - Posted 9 months ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Reinhard,

There currently aren't any locks on the language service registration but that would probably be a good idea to add them since if you start using it in the multi-threaded scenario (like when parsing) while updating the services, it could run into the scenario you illustrated.

Can you write our support address and mention this thread?  We will make some code updates and send you a preview build to test with yoru code as-is to see if it helps.  If not, we'll help you work around it another way.  Thanks!


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.