Reputation: 509
I have the following code:
private void HighlightSyntax(string syntax)
{
Regex regex = null;
switch (syntax)
{
case ".xml":
regex = new Regex(@"<\/?[^>\/]*>");
break;
}
if (regex != null)
{
Input.BeginUpdate();
// I want to save scrollbar position here and then restore it
// or maybe even disable it from being changed
int lastIndex = Input.SelectionStart;
int lastLength = Input.SelectionLength;
Input.SelectAll();
// gets matches
var matches = regex.Matches(Input.Text).Cast<Match>().ToArray();
if (matches.Length > 0) // divide into tasks and select all matches
{
Color color = Color.ForestGreen;
int wordsPerTask = 500;
int tasksAmount = (matches.Length / wordsPerTask) + 1;
int start = 0;
int end = matches.Length - 1;
Task[] tasks = new Task[tasksAmount];
for (int i = 0; i < tasksAmount; i++)
{ // dividing
start = matches.Length / tasksAmount * i;
end = matches.Length / tasksAmount * (i + 1) - 1;
var start1 = start;
var end1 = end;
tasks[i] = Task.Run(() => { SelectMatchesInArr(matches, start, end, color); } );
}
if (matches.Length - 1 - end > 0)
SelectMatchesInArr(matches, end + 1, matches.Length - 1, color);
Task.WaitAll(tasks);
}
Input.Select(lastIndex, lastLength);
Input.SelectionColor = Color.Black;
// Restore Input.ScrollBarPosition here
Input.EndUpdate();
}
}
// selects matches from start to end Indexes with Color color.
private void SelectMatchesInArr(Match[] matches, int startIndex, int endIndex, Color color)
{
for (int i = startIndex; i <= endIndex; i++)
{
int selectionStart = Input.SelectionStart;
lock (_locker)
{
Input.Select(matches[i].Index, matches[i].Length);
Input.SelectionColor = color;
Input.DeselectAll();
Input.SelectionStart = selectionStart;
Input.SelectionLength = 0;
}
}
}
It highlights syntax in richtexbox, if regex matches anything related to that syntax. It all worked until I decided to divide selecting into multiple tasks.
After dividing the selection into multiple tasks, my scrollbar position is not stable. Well, I want it to be stable, I don't want it to be changed via code. How do I prevent it from being changed if I have multiple tasks manipulating over richtextbox? What should I do in my situation? Also check comments in the code, they are written in order to help you explain what I want to do.
By the way, the BeginUpdate() and EndUpdate() methods are extension methods that have been taken from here: Hans Passant's derived from richtextbox class
Upvotes: 0
Views: 58
Reputation: 373
Maybe it would be better to use multithreading only for generating the list of matches and then use them for highlighting?
Also, it seems a bit dangerous to modify UI in multiple threads without any synchronization since it's possible that one thread would call 'Input.Select' and the other one 'Input.DeselectAll' before the first one will set the color.
Applying UI changes in one thread would eliminate that possibility.
Upvotes: 1