我有以下代码:
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;
}
}
}
如果正则表达式匹配与该语法相关的任何内容,它将突出显示richtexbox中的语法。一切都奏效,直到我决定将选择分为多个任务。
将选择分为多个任务后,我的滚动条位置不稳定。好吧,我希望它是稳定的,我不希望通过代码对其进行更改。如果我有多个任务在Richtextbox上进行操作,如何防止更改它?在这种情况下我该怎么办?还要检查代码中的注释,它们是为了帮助您解释我要做什么而编写的。
顺便说一下,BeginUpdate()和EndUpdate()方法是从此处获取的扩展方法:Hans Passant's derived from richtextbox class
答案 0 :(得分:1)
也许最好仅将多线程用于生成匹配项列表,然后将其用于突出显示?
另外,在没有任何同步的情况下在多个线程中修改UI似乎有些危险,因为一个线程可能会在第一个线程设置颜色之前调用“ Input.Select”,而另一个调用“ Input.DeselectAll”。
在一个线程中应用UI更改将消除这种可能性。