Неустранимая проблема пользовательского интерфейса в параллельном цикле - PullRequest
0 голосов
/ 18 мая 2018

Я создаю приложение блокнота на c # с использованием параллельной библиотеки задач, но при применении я применяю функцию поиска, и весь пользовательский интерфейс застревает.Я пытался вызвать метод, но все равно он не помог.Ниже приводится функция поиска.

private void toolStripButton1_Click_1(object sender, EventArgs e)
    {

        Parallel.For(0, GetRichTextBox().Text.LastIndexOf(toolStripTextBox1.Text) + 1, (int i) =>
        {
            GetRichTextBox().Find(toolStripTextBox1.Text, i, GetRichTextBox().TextLength, RichTextBoxFinds.None);
            GetRichTextBox().SelectionBackColor = Color.Orange;
            i = GetRichTextBox().Text.IndexOf(toolStripTextBox1.Text, i) + 1;
        });
    }

Следующий код является методом GetRichTextBox.

 public  RichTextBox GetRichTextBox()
    {
        Invoke(new MethodInvoker(delegate ()
        {
        TabPage tp = tabControl1.SelectedTab;
        if(tp!= null)
        {
            rtb = tp.Controls[0] as RichTextBox;
        }

        }));
        return rtb;
    }

1 Ответ

0 голосов
/ 18 мая 2018

Код: GetRichTextBox() вызывается в потоке пользовательского интерфейса (с помощью метода Invoke(...)).

В теле вашего параллельного цикла for вы вызываете этот метод 4 раза.Таким образом, большая часть параллельного тела вызывается в потоке пользовательского интерфейса, в результате чего ваше приложение перестает отвечать на запросы.


Тип исправления:

using System.Linq;
using System.Text.RegularExpressions;

private void toolStripButton1_Click_1(object sender, EventArgs e)
{
    // Get the textbox just once.
    var textBox = GetRichTextBox();
    // Set the selection color also just once.
    textBox.SelectionBackColor = Color.Orange;

    // get the text to find
    var textToFind = toolStripTextBox1.Text;
    // get the text to search in
    var completeText = textBox.Text;
<strong>
    // escape the text to find because we are using regex to find them
    var escapedTextToFind = Regex.Escape(textToFind);
    // find all the index of the search text int the complete text
    var indexes = Regex.Matches(completeText, escapedTextToFind)
        .OfType<Match>()
        .Select(m => m.Index);
</strong>
    // select every found index in the textbox
    foreach (var selectionStartIndex in indexes)
    {
        textBox.Select(selectionStartIndex, textToFind.Length);
    }
}

// No needs for invoke, since we want to do UI stuff on the UI thread
public RichTextBox GetRichTextBox()
{
    // instead of null checks, you can use the null conditional operators
    // see: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-conditional-operators
    return tabControl1?.SelectedTab?.Controls?[0] as RichTextBox;
}

Я сомневаюсь, что это сработает, потому что я верюВы можете выбрать несколько текстов одновременно.Поскольку большая часть этого кода работает в пользовательском интерфейсе, вы должны делать все это в пользовательском интерфейсе.Но если объем текста очень большой, а пользовательский интерфейс все еще зависает, вы можете выделить жирную часть параллельно.Но я думаю, что это излишне.

...