ошибка textBox3, ДОСТУПНАЯ ИЗ НИТИ ДРУГОГО, ЧЕМ НИТИ ОНА СОЗДАЛАСЬ во время выполнения запроса Plinq - PullRequest
0 голосов
/ 09 апреля 2020

У меня есть метод в другом классе, который выбирает все строки, которые содержат данный символ из textbox2, и печатает его в textbox3 при нажатии кнопки, но у меня возникает эта ошибка (textBox3 ДОСТУПЛЕНО ИЗ РЕЗЬБЫ ДРУГОЙ, ЧЕМ ЭТО НИТА БЫЛА СОЗДАНА ).

public void plinq()
    {
        List<string> lines = new List<string>(textBox2.Lines);
        List<string> lines2 = new List<string>();
        try
        {
            if (textBox3.InvokeRequired)
            {
                textBox3.Invoke(new Action(plinq));
            }
            else
            {
                lines.AsParallel().ForAll(K =>
                {
                    for (int i = 0; i < K.Length; i++)
                    {
                        if (lines[i].Contains(textBox4.Text))
                        {
                            lines2.Add(lines[i]);
                        }  
                    }
                    textBox3.Lines = lines2.ToArray();
                }); 
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }

enter image description here

, и она является кодом кнопки, где я вызываю метод

        private void button6_Click(object sender, EventArgs e)
    {
        textBox3.Text = "";
        int n = Convert.ToInt32(textBox1.Text);
        worker = new Worker(n, textBox2, textBox3, textBox4);
        Thread thread = new Thread(worker.plinq);
        sw.Start();
        thread.Start();
        //worker.plinq();
        sw.Stop();
        button6.Text = Convert.ToString(sw.Elapsed);
        sw.Reset();
    }

1 Ответ

2 голосов
/ 09 апреля 2020

Указанный дубликат довольно старый. Это не неточно - но это предшествует PLINQ.

Смотрите здесь:

MS Документация: Потенциальные ловушки с PLINQ

Избегайте вызовов не поточнобезопасных методов

Запись в не поточнобезопасные методы экземпляра из запроса PLINQ может привести к повреждению данных, которое может или не может go не обнаружено в вашей программе. Это также может привести к исключениям. В следующем примере несколько потоков будут пытаться вызвать метод FileStream.Write одновременно, который не поддерживается классом.

...

Предпочитать ForAll для ForEach, когда это возможно

Хотя PLINQ выполняет запрос в нескольких потоках, если вы используете результаты в foreach l oop (для каждого в Visual Basi c), тогда результаты запроса должны быть объединены обратно в один поток и последовательно доступны для перечислителя. В некоторых случаях это неизбежно; однако, когда это возможно, используйте метод ForAll, чтобы каждый поток мог выводить свои собственные результаты, например, путем записи в потокобезопасную коллекцию, такую ​​как System.Collections.Concurrent.ConcurrentBag.

Та же проблема применима Parallel.ForEach. Другими словами, source.AsParallel (). Where (). ForAll (...) должен быть строго предпочтен Parallel.ForEach (source.AsParallel (). Where (), ...).

...

Помните о проблемах схожести потоков

Некоторые технологии, например, совместимость COM для компонентов однопотоковой квартиры (STA), Windows форм, и Windows Presentation Foundation (WPF), наложить ограничения по схожести потоков, которые требуют выполнения кода в указанном потоке c. Например, в Windows Forms и WPF доступ к элементу управления возможен только в том потоке, в котором он был создан. Если вы пытаетесь получить доступ к общему состоянию элемента управления Windows Forms в запросе PLINQ, возникает исключение, если вы работаете в отладчике. (Этот параметр можно отключить.) Однако, если ваш запрос используется в потоке пользовательского интерфейса, вы можете получить доступ к элементу управления с foreach l oop, который перечисляет результаты запроса, поскольку этот код выполняется только в одном потоке.

...

Пожалуйста, обновите ваше сообщение:

Q1: В какой именно строке произошла ошибка?

Q2: Это происходит в отладчик, вне отладчика, или и то и другое?

Q3: Помог ли рефакторинг вашего кода с какими-либо предложениями по ссылке?

Q4: Рефакторинг вашего кода такой, что все изменения в «TextBox3» возникает ВНЕ PLinq (и встречается ТОЛЬКО в потоке пользовательского интерфейса) help?

...