void queueRealtimeChange(object state) { // Wait for VS to actually update the content System.Threading.Thread.Sleep(20); _syncContext.Post((s) => { var StartPoint = (TextPoint)state; try { Logger.Write("About to lock on text point list"); lock (_dirtyRealtimeDocuments) { var project = StartPoint.Parent.Parent.ProjectItem.ContainingProject.FullName; var file = StartPoint.Parent.Parent.FullName; var content = StartPoint.Parent.CreateEditPoint(StartPoint.Parent.StartPoint).GetText(StartPoint.Parent.EndPoint); var document = StartPoint.Parent.Parent; clearOutdatedRealtimeChanges(file); _dirtyRealtimeDocuments.Add(new KeyValuePair <RealtimeChangeMessage, Document>(new RealtimeChangeMessage(project, file, content), document)); } } catch (Exception ex) { Logger.Write(ex); } }, state); _changeTracker.Start(() => { _syncContext.Post((s) => { lock (_dirtyRealtimeDocuments) { _client.QueueRealtimeChange( new RealtimeChangeList(_dirtyRealtimeDocuments.GroupBy(x => x.Key).Select(x => x.Key))); } }, null); }); }