Αν κάτι χρειάζεται async είναι η ColoriseRTB. Αυτό όμως δεν γίνεται καθώς ο κώδικας έχει τα ίδια προβλήματα με τον προηγούμενο. Η ColoriseRTB εξακολουθεί να "πειράζει" τα controls οπότε απαιτείται Invoke. Επιπλέον, η Colorise κάνει δύο πράγματα, ψάχνει για λέξεις και αλλάζει τα controls. Αυτό είναι λάθος σχεδιασμός και ένα από τα αποτελέσματα του είναι ότι δεν μπορεί να εκτελεστεί ασύγχρονα.
Τουλάχιστον αυτή η μέθοδος θα πρέπει να σπάσει στα δύο, μία SearchWords η οποία θα έχει ως παρεμέτρους τις γραμμές που πρέπει να αναζητηθούν και θα επιστρέφει τα locations, και μία colorize η οποία με βάση αυτή τη λίστα θα αλλάζει το χρώμα των λέξεων. Η SearchWords άνετα μπορεί να εκτελεστεί ασύγχρονα. Η Colorize όχι.
Μπορούν να γίνουν και άλλες απλοποιήσεις, όπως πχ. να χρησιμοποιηθεί η RichTextBox.Select αντί για την αλλαγή των selection μέσω properties, για να μειωθούν οι καθυστερήσεις που οφείλονται στην επεξεργασία των αλλαγών των properties (π.χ. changed events, πιθανά redraws).
Τέλος, αν ο αριθμός των λέξεων είναι μικρός μπορείς να χρησιμοποιήσεις pattern matching για να ψάξεις για όλες με μία κλήση της Matches, π.χ. Regex.Matches(input, "Word1|Word2|Word3").
Μπορείς να φτιάξεις ένα function το οποίο θα φτιάχνει ένα pattern ενώνοντας όλες τις λέξεις με διαχωριστικό το '|' και θα επιστρέφει τα αποτελέσματα όπως παρακάτω:
Function SearchWords(input As String, words As String()) As IEnumerable(Of Tuple(Of String, Integer, Integer))
Dim pattern = String.Join("|", words)
Dim matches = Regex.Matches(input, pattern)
Dim indexes = From m As Match In matches
Select Tuple.Create(m.Value, m.Index, m.Length)
Return indexes
End Function
Εδώ χρησιμοποιώ και λίγο LINQ για να επιστρέψω τα αποτελέσματα που θέλω χωρίς να φτιάξω ξεχωριστή κλάση
Μετά μπορώ άνετα να κάνω αναζήτηση με μία μόνο κλήση, για όλες τις λέξεις όπως παρακάτω:
Dim text = "This is some text I want to search. Try to find some words here"
Dim search As String() = {"some", "to"}
Dim results = SearchWords(text, search)
For Each result In results
Console.WriteLine("Found {0} at {1}:{2}", result.Item1, result.Item2, result.Item3)
Next
Console.ReadKey()
Παναγιώτης Καναβός, Freelancer
Twitter: http://www.twitter.com/pkanavos