EditorSearchOption.FindNext Async?

SyntaxEditor for WPF Forum

Posted 7 years ago by \アッカリーン/
Version: 12.2.0571
Avatar

Hey guys, had a question...

Looking through the documentation the current search feature uses a non-async method call, which ends up running on the UI thread:

                StatusBarError(StatusBarChangeType.Informational, "Searching...", true);

                EditorSearchOptions eso = new EditorSearchOptions();
                eso.FindText = tb.Text;
                eso.PatternProvider = SearchPatternProviders.Normal;
                var find = lastEditor.ActiveView.Searcher.FindNext(eso);

                if (find.Results.Count < 1)
                {
                    StatusBarError(StatusBarChangeType.Error, string.Format("Text '{0}' not found", tb.Text), false);
                }
                else
                {
                    StatusBarError(StatusBarChangeType.Reset, "", false);
                }

I have a function that changes the status bar for informational purposes, as you can see above, but when the UI thread locks, the UI won't update, and so "Searching..." is never displayed to the user. Now, I'd be okay with the Editor switching to IsEnabled = false, or something, while searching, but is there a way to at least have this operation happen asynchronously, so the application doesn't appear frozen to the user, and other things can display? The project I'm working on has me often searching through 5-15 MB XML documents, sometimes larger, so this would be pretty useful. Other than that, the XML documents load and highlight immediately, and so far the control's been great to work with.

Thanks again for your time-

Comments (3)

Answer - Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi, we have a lower-level search API you can use.  In your code sample you used the EditorView search API but the documentation in the "Text/Parsing Framework - Advanced Text Features / Low-Level Search Operations" topic talks about the document snapshot search API.  Snapshots are thread safe so that you can run the search operations listed there on them in a worker thread.  Then return the result set when you're done and update your UI.


Actipro Software Support

Posted 7 years ago by \アッカリーン/
Avatar

Thank you very very much. I'll start working on that now.

Posted 7 years ago by \アッカリーン/
Avatar

I implemented the solution above and it works wonderfully. In case anyone else would like some sample code, here's how I did it:

 

                lastEditor.Document.IsReadOnly = true;

                StatusBarError(StatusBarChangeType.Informational, "Searching...", true);

                BackgroundWorker bg = new BackgroundWorker();

                var processText = tb.Text;
                var snapshot = lastEditor.Document.CurrentSnapshot;

                bg.DoWork += (a, b) =>
                {
                    EditorSearchOptions eso = new EditorSearchOptions();
                    eso.FindText = processText;
                    eso.PatternProvider = SearchPatternProviders.Normal;
                    b.Result = snapshot.FindNext(eso, lastEditor.Caret.Offset, true);
                };

                bg.RunWorkerCompleted += (a, b) =>
                {
                    var find = (ISearchResultSet)b.Result;
                    if (find.Results.Count < 1)
                    {
                        StatusBarError(StatusBarChangeType.Error, string.Format("Text '{0}' not found", processText), false);
                    }
                    else
                    {
                        StatusBarError(StatusBarChangeType.Reset, "", false);

                        lastEditor.ActiveView.Selection.SelectRange(find.Results[0].TextRange);

                        if (find.Wrapped)
                        {
                            StatusBarError(StatusBarChangeType.Informational, string.Format("Search passed the end of the document"), false);
                        }
                    }

                    lastEditor.Document.IsReadOnly = false;
                };

                bg.RunWorkerAsync();

[Modified 7 years ago]

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.