internal static void AddDocumentsSimilarToDistribution(NodeControl node_control_, WebLibraryDetail web_library_detail, ExpeditionDataSource eds, float[] tags_distribution) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); ASSERT.Test(eds != null); // Get the most similar PDFDocuments int[] doc_ids = LDAAnalysisTools.GetDocumentsSimilarToDistribution(eds.LDAAnalysis, tags_distribution); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); for (int i = 0; i < 10 && i < doc_ids.Length; ++i) { int doc_id = doc_ids[i]; string fingerprint = eds.docs[doc_id]; PDFDocument pdf_document = web_library_detail.Xlibrary.GetDocumentByFingerprint(fingerprint); if (null == pdf_document) { Logging.Warn("Couldn't find similar document with fingerprint {0}", fingerprint); } else { PDFDocumentNodeContent content = new PDFDocumentNodeContent(pdf_document.Fingerprint, pdf_document.LibraryRef.Id); NodeControlAddingByKeyboard.AddChildToNodeControl(node_control_, content, false); } } }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("MainWindow::Dispose({0}) @{1}", disposing, dispose_count); try { if (dispose_count == 0) { WPFDoEvents.InvokeInUIThread(() => { // Get rid of managed resources ObjTabWelcome.GetGoing -= ObjTabWelcome_GetGoing; ObjStartPage?.Dispose(); ipc_server?.Stop(); }, Dispatcher); } ObjStartPage = null; keyboard_hook = null; ipc_server = null; DataContext = null; } catch (Exception ex) { Logging.Error(ex); } ++dispose_count; }
private static void Display(string title, string useful_text_heading, string useful_text_subheading, string comments_label, bool display_exception_section, bool display_faq_link, Exception ex) { try { Logging.Info(string.Format("About to display client stats: {0}", useful_text_heading), ex); if (!ShutdownableManager.Instance.IsShuttingDown) { WPFDoEvents.InvokeInUIThread(() => { UnhandledExceptionMessageBox mb = new UnhandledExceptionMessageBox(); mb.Title = title; mb.PopulateText(useful_text_heading, useful_text_subheading, comments_label, display_faq_link); mb.PopulateException(ex, display_exception_section); mb.PopulateLog(); mb.PopulateMachineStats(); mb.ShowDialog(); }); } else { throw new Exception(String.Format("Unhandled Exception Display while shutting down:\nHeading: {0}\nOriginal Exception: {1}", useful_text_heading, ex), ex); } } catch (Exception ex2) { Logging.Error(ex2, "There was an error while trying to display an UnhandledExceptionMessageBox. Bailing so that we don't get an infinite-recurse!"); } }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFReadingControl::Dispose({0}) @{1}", disposing, dispose_count); try { if (dispose_count == 0) { WPFDoEvents.InvokeInUIThread(() => { // Get rid of managed resources PDFRendererControlArea.Children.Clear(); pdf_renderer_control?.Dispose(); pdf_renderer_control_stats?.pdf_document.PDFRenderer.FlushCachedPageRenderings(); }, Dispatcher); } pdf_renderer_control = null; pdf_renderer_control_stats = null; } catch (Exception ex) { Logging.Error(ex); } ++dispose_count; }
private static void ExpandAuthors(PDFDocument doc, NodeControl node_control) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); ASSERT.Test(doc != null); FeatureTrackingManager.Instance.UseFeature(Features.Brainstorm_ExploreLibrary_Document_Authors); if (doc != null) { string authors = doc.AuthorsCombined; if (String.IsNullOrEmpty(authors) || Constants.UNKNOWN_AUTHORS == authors) { return; } WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); List <NameTools.Name> names = new List <NameTools.Name>(); string[] authors_split = NameTools.SplitAuthors_LEGACY(authors); foreach (string author_split in authors_split) { string first_names, last_name; NameTools.SplitName_LEGACY(author_split, out first_names, out last_name); string initial = String.IsNullOrEmpty(first_names) ? null : first_names.Substring(0, 1); PDFAuthorNodeContent pdf_author = new PDFAuthorNodeContent(doc.LibraryRef.Id, last_name, initial); NodeControlAddingByKeyboard.AddChildToNodeControl(node_control, pdf_author, false); } }); } }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFDocumentNodeContentControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { library_index_hover_popup?.Dispose(); } library_index_hover_popup = null; }); WPFDoEvents.SafeExec(() => { ToolTip = ""; }); WPFDoEvents.SafeExec(() => { node_control = null; pdf_document_node_content = null; }); WPFDoEvents.SafeExec(() => { DataContextChanged -= PDFDocumentNodeContentControl_DataContextChanged; DataContext = null; }); ++dispose_count; }); }
private static void ExpandAnnotations(PDFDocument doc, NodeControl node_control) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); ASSERT.Test(doc != null); FeatureTrackingManager.Instance.UseFeature(Features.Brainstorm_ExploreLibrary_Document_Annotations); if (doc != null) { var annotations = doc.GetAnnotations(); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); foreach (var annotation in annotations) { if (!annotation.Deleted) { PDFAnnotationNodeContent content = new PDFAnnotationNodeContent(doc.LibraryRef.Id, doc.Fingerprint, annotation.Guid.Value); NodeControlAddingByKeyboard.AddChildToNodeControl(node_control, content, false); } } }); } }
private static void ExpandCitationsOutbound(PDFDocument doc, NodeControl node_control) { FeatureTrackingManager.Instance.UseFeature(Features.Brainstorm_ExploreLibrary_Document_CitationsOutbound); ASSERT.Test(doc != null); if (doc != null) { List <Citation> citations = doc.PDFDocumentCitationManager.GetOutboundCitations(); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); foreach (var citation in citations) { // NB: We assume the citations are from the same library!! PDFDocumentNodeContent content = new PDFDocumentNodeContent(citation.fingerprint_inbound, doc.LibraryRef.Id); if (!content.PDFDocument.Deleted) { NodeControlAddingByKeyboard.AddChildToNodeControl(node_control, content, false); } } }); } }
protected virtual void Dispose(bool disposing) { Logging.Debug("StringNodeContentControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { // Get rid of managed resources / get rid of cyclic references: fader?.Dispose(); } fader = null; }); WPFDoEvents.SafeExec(() => { MouseDoubleClick -= StringNodeContentControl_MouseDoubleClick; KeyDown -= StringNodeContentControl_KeyDown; TxtEdit.LostFocus -= edit_text_box_LostFocus; TxtEdit.PreviewKeyDown -= edit_text_box_PreviewKeyDown; }); WPFDoEvents.SafeExec(() => { DataContext = null; }); ++dispose_count; }); }
public void RequestSync(SyncRequest sync_request) { bool user_wants_intervention = KeyboardTools.IsCTRLDown() || !ConfigurationManager.Instance.ConfigurationRecord.SyncTermsAccepted; WPFDoEvents.SetHourglassCursor(); SafeThreadPool.QueueUserWorkItem(o => { GlobalSyncDetail global_sync_detail = GenerateGlobalSyncDetail(); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.ResetHourglassCursor(); SyncControlGridItemSet scgis = new SyncControlGridItemSet(sync_request, global_sync_detail); scgis.AutoTick(); if (scgis.CanRunWithoutIntervention() && !user_wants_intervention) { Sync(scgis); } else { SyncControl sync_control = new SyncControl(); sync_control.SetSyncParameters(scgis); sync_control.Show(); } }); }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("MainWindow::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { ipc_server?.Stop(); } }); WPFDoEvents.SafeExec(() => { ObjStartPage = null; keyboard_hook = null; ipc_server = null; }); WPFDoEvents.SafeExec(() => { DataContext = null; }); ++dispose_count; }); }
internal void RefreshSyncControl(SyncControlGridItemSet scgis_previous, SyncControl sync_control) { WPFDoEvents.SetHourglassCursor(); SafeThreadPool.QueueUserWorkItem(o => { // // Explicitly instruct the sync info collector to perform a swift scan, which DOES NOT include // collecting the precise size of every document in every Qiqqa library (which itself is a *significant* // file system load when you have any reasonably large libraries like I do. [GHo] // // TODO: fetch and cache document filesizes in the background, so we can improve on the accuracy of // our numbers in a future call to this method. // GlobalSyncDetail global_sync_detail = GenerateGlobalSyncDetail(tally_library_storage_size: false); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.ResetHourglassCursor(); SyncControlGridItemSet scgis = new SyncControlGridItemSet(scgis_previous.sync_request, global_sync_detail); scgis.AutoTick(); sync_control.SetSyncParameters(scgis); }); }); }
private static void DoPostUpgrade() { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); // NB NB NB NB: You CANT USE ANYTHING IN THE USER CONFIG AT THIS POINT - it is not yet decided until LOGIN has completed... WPFDoEvents.InvokeInUIThread(() => { StatusManager.Instance.UpdateStatus("AppStart", "Loading themes"); Theme.Initialize(); DualTabbedLayout.GetWindowOverride = delegate() { return(new StandardWindow()); }; // Force tooltips to stay open ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(3600000)); }); // Make sure the data directories exist... if (!Directory.Exists(ConfigurationManager.Instance.BaseDirectoryForUser)) { Directory.CreateDirectory(ConfigurationManager.Instance.BaseDirectoryForUser); } // and kick off the Login Dialog to start the application proper: WPFDoEvents.InvokeAsyncInUIThread(() => ShowLoginDialog()); // NB NB NB NB: You CANT USE ANYTHING IN THE USER CONFIG AT THIS POINT - it is not yet decided until LOGIN has completed... }
private void ButtonJoinCreate_Click(object sender, RoutedEventArgs e) { FeatureTrackingManager.Instance.UseFeature(Features.StartPage_CreateIntranetLibrary); if (String.IsNullOrEmpty(TxtPath.Text)) { MessageBoxes.Error("Please enter a path to your Intranet Library."); return; } string db_base_path = TxtPath.Text; string db_title = TxtTitle.Text; string db_description = TxtDescription.Text; SafeThreadPool.QueueUserWorkItem(o => { bool validation_successful = EnsureIntranetLibraryExists(db_base_path, db_title, db_description); if (validation_successful) { WPFDoEvents.InvokeInUIThread(() => { Close(); }); } }); }
internal static void Install(BundleLibraryManifest manifest, string library_bundle_filename) { WPFDoEvents.AssertThisCodeIs_NOT_RunningInTheUIThread(); WebLibraryDetail web_library_detail = WebLibraryManager.Instance.GetLibrary(manifest.Id); if (null != web_library_detail) { MessageBoxes.Info("You already have a version of this Bundle Library. Please ensure you close all windows that use this library after the latest has been downloaded."); } string library_directory = WebLibraryDetail.GetLibraryBasePathForId(manifest.Id); Directory.CreateDirectory(library_directory); // Unzip the bundle string parameters = String.Format("-y x \"{0}\" -o\"{1}\"", library_bundle_filename, library_directory); using (Process process = ProcessSpawning.SpawnChildProcess(ConfigurationManager.Instance.Program7ZIP, parameters)) { using (ProcessOutputReader process_output_reader = new ProcessOutputReader(process)) { process.WaitForExit(); Logging.Info("7ZIP Log Bundle Install progress:\n{0}", process_output_reader.GetOutputsDumpStrings()); } } // Reflect this new bundle WebLibraryDetail new_web_library_detail = WebLibraryManager.Instance.UpdateKnownWebLibraryFromBundleLibraryManifest(manifest, suppress_flush_to_disk: false); WPFDoEvents.InvokeInUIThread(() => { MainWindowServiceDispatcher.Instance.OpenLibrary(new_web_library_detail); }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("ReadOutLoudManager::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { // Get rid of managed resources speech_synthesizer?.Dispose(); } speech_synthesizer = null; }); WPFDoEvents.SafeExec(() => { current_prompt = null; last_words?.Clear(); last_words = null; }); ++dispose_count; }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("SpeedReadControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { // Get rid of managed resources and background threads playing = false; if (thread != null) { thread.Join(); } }); WPFDoEvents.SafeExec(() => { words.Clear(); }); WPFDoEvents.SafeExec(() => { DataContext = null; }); ++dispose_count; }); }
internal static void MeasureUIResponsivenessBackground() { // measure UI responsiveness collected_data.ProcessCurrentRecord(shift: false, (rec, _) => { rec.UIResponsiveness.threadpool_start_delay_bg = resp_housekeeping.clk2Test.ElapsedTicks; resp_housekeeping.clkBackground = Stopwatch.StartNew(); }); // Relinquish control to the UI thread temporarily to help check UI responsiveness WPFDoEvents.InvokeInUIThread(() => { // do nothing. Just measure... collected_data.ProcessCurrentRecord(shift: false, (rec, _) => { rec.UIResponsiveness.ui_invoke_bg_duration = resp_housekeeping.clkBackground.ElapsedTicks; }); }); collected_data.ProcessCurrentRecord(shift: false, (rec, _) => { rec.UIResponsiveness.ui_roundtrip_bg_duration = resp_housekeeping.clkBackground.ElapsedTicks; resp_housekeeping.running--; }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFAnnotationNodeContentControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { library_index_hover_popup?.Dispose(); ToolTipClosing -= PDFDocumentNodeContentControl_ToolTipClosing; ToolTipOpening -= PDFDocumentNodeContentControl_ToolTipOpening; } }); WPFDoEvents.SafeExec(() => { // Clear the references for sanity's sake pdf_annotation_node_content = null; library_index_hover_popup = null; }); ++dispose_count; }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("LibraryCatalogOverviewControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { // Get rid of managed resources / get rid of cyclic references: library_index_hover_popup?.Dispose(); } }); WPFDoEvents.SafeExec(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); if (dispose_count == 0) { WizardDPs.ClearPointOfInterest(PanelSearchScore); } }); WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { WizardDPs.ClearPointOfInterest(ObjLookInsidePanel); } }); WPFDoEvents.SafeExec(() => { TextTitle.MouseLeftButtonUp -= TextTitle_MouseLeftButtonUp; ButtonOpen.ToolTipOpening -= HyperlinkPreview_ToolTipOpening; ButtonOpen.ToolTipClosing -= HyperlinkPreview_ToolTipClosing; ListSearchDetails.SearchClicked -= ListSearchDetails_SearchSelectionChanged; DataContextChanged -= LibraryCatalogOverviewControl_DataContextChanged; }); WPFDoEvents.SafeExec(() => { DataContext = null; }); WPFDoEvents.SafeExec(() => { // Clear the references for sanity's sake library_index_hover_popup = null; drag_drop_helper = null; }); ++dispose_count; }); }
private void AITagsRegenerated_NON_GUI_THREAD(IAsyncResult ar) { WPFDoEvents.InvokeInUIThread(() => { AITagsRegenerated_GUI_THREAD(); } ); }
private void Instance_WebLibrariesChanged() { WPFDoEvents.InvokeInUIThread(() => { Refresh(); }, priority: DispatcherPriority.Background); }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFTextSentenceLayer::Dispose({0}) @{1}", disposing, dispose_count); try { if (null != drag_area_tracker) { WPFDoEvents.InvokeInUIThread(() => { try { foreach (var el in Children) { IDisposable node = el as IDisposable; if (null != node) { node.Dispose(); } } } catch (Exception ex) { Logging.Error(ex); } try { ClearChildren(); Children.Clear(); } catch (Exception ex) { Logging.Error(ex); } drag_area_tracker.OnDragStarted -= drag_area_tracker_OnDragStarted; drag_area_tracker.OnDragInProgress -= drag_area_tracker_OnDragInProgress; drag_area_tracker.OnDragComplete -= drag_area_tracker_OnDragComplete; }, Dispatcher); } // Clear the references for sanity's sake pdf_renderer_control_stats = null; drag_area_tracker = null; text_selection_manager = null; DataContext = null; } catch (Exception ex) { Logging.Error(ex); } ++dispose_count; //base.Dispose(disposing); // parent only throws an exception (intentionally), so depart from best practices and don't call base.Dispose(bool) }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFHandLayer::Dispose({0}) @{1}", disposing, dispose_count); try { if (0 == dispose_count) { WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.AssertThisCodeIsRunningInTheUIThread(); try { foreach (var el in Children) { IDisposable node = el as IDisposable; if (null != node) { node.Dispose(); } } } catch (Exception ex) { Logging.Error(ex); } try { Children.Clear(); } catch (Exception ex) { Logging.Error(ex); } MouseDown -= PDFHandLayer_MouseDown; MouseUp -= PDFHandLayer_MouseUp; MouseMove -= PDFHandLayer_MouseMove; DataContext = null; }, Dispatcher); } // Clear the references for sanity's sake pdf_renderer_control_stats = null; pdf_renderer_control = null; } catch (Exception ex) { Logging.Error(ex); } ++dispose_count; //base.Dispose(disposing); // parent only throws an exception (intentionally), so depart from best practices and don't call base.Dispose(bool) }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFRendererControl::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { if (!ShutdownableManager.Instance.IsShuttingDown) { pdf_renderer_control_stats?.pdf_document.QueueToStorage(); } } }); WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { // Get rid of managed resources List <PDFRendererPageControl> children = new List <PDFRendererPageControl>(); foreach (PDFRendererPageControl child in ObjPagesPanel.Children.OfType <PDFRendererPageControl>()) { children.Add(child); } ObjPagesPanel.Children.Clear(); foreach (PDFRendererPageControl child in children) { WPFDoEvents.SafeExec(() => { child.Dispose(); }); } } }); WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { pdf_renderer_control_stats?.pdf_document.FlushCachedPageRenderings(); } Dispatcher.ShutdownStarted -= Dispatcher_ShutdownStarted; }); WPFDoEvents.SafeExec(() => { pdf_renderer_control_stats = null; }); ++dispose_count; }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFInkLayer::Dispose({0}) @{1}", disposing, dispose_count); try { if (0 == dispose_count) { WPFDoEvents.InvokeInUIThread(() => { ObjInkCanvas.StrokeCollected -= ObjInkCanvas_StrokeCollected; ObjInkCanvas.StrokeErased -= ObjInkCanvas_StrokeErased; ObjInkCanvas.SelectionMoved -= ObjInkCanvas_SelectionMoved; ObjInkCanvas.SelectionResized -= ObjInkCanvas_SelectionResized; ObjInkCanvas.RequestBringIntoView -= ObjInkCanvas_RequestBringIntoView; try { foreach (var el in Children) { IDisposable node = el as IDisposable; if (null != node) { node.Dispose(); } } } catch (Exception ex) { Logging.Error(ex); } try { Children.Clear(); } catch (Exception ex) { Logging.Error(ex); } }, Dispatcher); } // Clear the references for sanity's sake pdf_renderer_control_stats = null; DataContext = null; } catch (Exception ex) { Logging.Error(ex); } ++dispose_count; //base.Dispose(disposing); // parent only throws an exception (intentionally), so depart from best practices and don't call base.Dispose(bool) }
private void RepopulatePanels(PDFDocument doc) { var links = doc.PDFDocumentCitationManager.GetLinkedDocuments(); WPFDoEvents.InvokeInUIThread(() => { CitationsUserControl.PopulatePanelWithCitations(DocsPanel_Linked, doc, links, Features.LinkedDocument_InfoBar_OpenDoc); }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFTextSentenceLayer::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { if (dispose_count == 0) { foreach (var el in Children) { IDisposable node = el as IDisposable; if (null != node) { node.Dispose(); } } } }); WPFDoEvents.SafeExec(() => { ClearChildren(); Children.Clear(); }); WPFDoEvents.SafeExec(() => { if (drag_area_tracker != null) { drag_area_tracker.OnDragStarted -= drag_area_tracker_OnDragStarted; drag_area_tracker.OnDragInProgress -= drag_area_tracker_OnDragInProgress; drag_area_tracker.OnDragComplete -= drag_area_tracker_OnDragComplete; } Dispatcher.ShutdownStarted -= Dispatcher_ShutdownStarted; }); WPFDoEvents.SafeExec(() => { // Clear the references for sanity's sake pdf_renderer_control = null; drag_area_tracker = null; text_selection_manager = null; }); WPFDoEvents.SafeExec(() => { DataContext = null; }); ++dispose_count; //base.Dispose(disposing); // parent only throws an exception (intentionally), so depart from best practices and don't call base.Dispose(bool) }); }
/// <summary> /// Always call this using the form xyz.NotifyPropertyChanged(nameof(yyy.ZZZ)), where ZZZ is the property that just got updated. /// That way the compiler will catch any property name changes. /// </summary> /// <param name="property_name"></param> public void NotifyPropertyChanged(string property_name) { // if (Application.Current == null || Application.Current.Dispatcher.Thread == Thread.CurrentThread) // as per: https://stackoverflow.com/questions/5143599/detecting-whether-on-ui-thread-in-wpf-and-winforms#answer-14280425 // and: https://stackoverflow.com/questions/2982498/wpf-dispatcher-the-calling-thread-cannot-access-this-object-because-a-differen/13726324#13726324 WPFDoEvents.InvokeInUIThread(() => { NotifyPropertyChanged_THREADSAFE(property_name); }); }
protected virtual void Dispose(bool disposing) { Logging.Debug("PDFAnnotationLayer::Dispose({0}) @{1}", disposing, dispose_count); WPFDoEvents.InvokeInUIThread(() => { WPFDoEvents.SafeExec(() => { foreach (var el in Children) { IDisposable node = el as IDisposable; if (null != node) { node.Dispose(); } } }); WPFDoEvents.SafeExec(() => { Children.Clear(); }); WPFDoEvents.SafeExec(() => { WizardDPs.ClearPointOfInterest(this); }); WPFDoEvents.SafeExec(() => { if (drag_area_tracker != null) { drag_area_tracker.OnDragComplete -= drag_area_tracker_OnDragComplete; } Dispatcher.ShutdownStarted -= Dispatcher_ShutdownStarted; }); WPFDoEvents.SafeExec(() => { // Clear the references for sanity's sake pdf_document = null; drag_area_tracker = null; }); WPFDoEvents.SafeExec(() => { DataContext = null; }); ++dispose_count; //base.Dispose(disposing); // parent only throws an exception (intentionally), so depart from best practices and don't call base.Dispose(bool) }); }