-1

i have a method in another class that select all the lines that contains given char from textbox2,and print it to textbox3 on button_click but i'm having this error (textBox3 ACCESSED FROM A THREAD OTHER THAN THE THREAD IT WAS CREATED ON).

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

and her is the code of the button where i am calling the method

        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();
    }
Mhd Azhar
  • 27
  • 3
  • Does this answer your question? [Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on](https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the) – Progman Apr 09 '20 at 20:27

1 Answers1

2

The cited duplicate is pretty old. It's not inaccurate - but it pre-dates PLINQ.

Look here:

MS Documentation: Potential pitfalls with PLINQ

Avoid calls to non-thread-safe methods

Writing to non-thread-safe instance methods from a PLINQ query can lead to data corruption which may or may not go undetected in your program. It can also lead to exceptions. In the following example, multiple threads would be attempting to call the FileStream.Write method simultaneously, which is not supported by the class.

...

Prefer ForAll to ForEach when it is possible

Although PLINQ executes a query on multiple threads, if you consume the results in a foreach loop (For Each in Visual Basic), then the query results must be merged back into one thread and accessed serially by the enumerator. In some cases, this is unavoidable; however, whenever possible, use the ForAll method to enable each thread to output its own results, for example, by writing to a thread-safe collection such as System.Collections.Concurrent.ConcurrentBag.

The same issue applies to Parallel.ForEach. In other words, source.AsParallel().Where().ForAll(...) should be strongly preferred to Parallel.ForEach(source.AsParallel().Where(), ...).

...

Be aware of thread affinity issues

Some technologies, for example, COM interoperability for Single-Threaded Apartment (STA) components, Windows Forms, and Windows Presentation Foundation (WPF), impose thread affinity restrictions that require code to run on a specific thread. For example, in both Windows Forms and WPF, a control can only be accessed on the thread on which it was created. If you try to access the shared state of a Windows Forms control in a PLINQ query, an exception is raised if you are running in the debugger. (This setting can be turned off.) However, if your query is consumed on the UI thread, then you can access the control from the foreach loop that enumerates the query results because that code executes on just one thread.

...

Please update your post:

Q1: Exactly which line is the error occurring on?

Q2: Is it occurring in the debugger, outside of the debugger, or both?

Q3: Did refactoring your code with any of the suggestions in the link help?

Q4: Does refactoring your code such that all modifications to "TextBox3" occur OUTSIDE of PLinq (and occur ONLY on the UI thread) help?

FoggyDay
  • 11,962
  • 4
  • 34
  • 48
  • first i am sorry ,but i t's my first time dealing with threads and Plinq ,that's why i am confused.to answer your questions:Q1:the error occurred at the line (textBox3.Lines = lines2.ToArray();) but visual studio highlight all the lines inside of AsParallel.ForAll loop.Q2 both.Q3: no.Q4: when i but TextBox3 outside the ForAll loop i don't get the results that i want. – Mhd Azhar Apr 09 '20 at 21:08
  • 1
    I doubt "System.InvalidOperationException" is the result you want,either ;) You simply *shouldn't* try updating TextBox3 (which executes on the UI thread) from inside of a parallel "ForAll()" loop. There's no *NEED* to parallelize the operation anyway! Just refactor your code - it's as simple as that :) – FoggyDay Apr 09 '20 at 23:57
  • 1
    thanks a lot for the help,i did eventuality refactor my code ,it's the best and simplest solution as you said – Mhd Azhar Apr 11 '20 at 00:05