-2

I am trying to convert two different .txt files from lower case to upper case and the main objective is to measure and display the execution time.

Everything goes well if the files are saved with upper cases in my predefined path and the program displays the execution time. In my GUI however, texts do not convert because of the following exception in text-boxes:

System.InvalidOperationException: Cross-thread operation not valid: Control "textBox2" accessed from a thread other than the thread it was created on.

namespace Threads
{
    public partial class Form1 : Form
    {   String prim= @"C:\Users\Wheelz\Desktop\Laborator09\fis1.txt";
        String secund= @"C:\Users\Wheelz\Desktop\Laborator09\fis2.txt";
        public Form1()'
        {
            InitializeComponent();
        }
    private void button1_Click(object sender, EventArgs e)
    {
        var read = File.ReadAllText(prim);
        textBox1.Text = read;

    }

    private void button2_Click(object sender, EventArgs e)
    {
        var read = File.ReadAllText(secund);
        textBox2.Text = read;

    }
    private void modifica1()
    {
        var read = File.ReadAllText(prim);
        read = read.ToUpper();
        File.WriteAllText(@"C:\Users\Wheelz\Desktop\Laborator09\fis1upper.txt", read);
        textBox1.Text = textBox1.Text.ToUpper();

    }
    private void modifica2()
    {

        var read = File.ReadAllText(prim);
        read = read.ToUpper();
        File.WriteAllText(@"C:\Users\Wheelz\Desktop\Laborator09\fis2upper.txt", read);
        textBox2.Text = textBox2.Text.ToUpper() ;


    }

    private void timp_Click(object sender, EventArgs e)
    {
        Thread firstThread = new Thread(new ThreadStart(modifica1));
        Thread secondThread = new Thread(new ThreadStart(modifica2));
        var ceas= new Stopwatch();
        ceas.Start();
        firstThread.Start();
        secondThread.Start();
        ceas.Stop();

        if (ceas.ElapsedMilliseconds == 1)
        {
            cron.Text = ceas.ElapsedMilliseconds.ToString() + "  milisecundă";
        }
        else
        {
            if ((ceas.ElapsedMilliseconds < 20))

                cron.Text = ceas.ElapsedMilliseconds.ToString() + "   milisecunde";

            else
                cron.Text = ceas.ElapsedMilliseconds.ToString() + "  de milisecunde";
        }



    }
}

}

Ali Deym
  • 142
  • 8
  • 3
    The exception message is pretty clear. What is the question? – Rufus L May 13 '20 at 17:52
  • Can you please [edit] the question *showing* your research on "System.InvalidOperationException: Cross-thread operation not valid" error or to clarify what you actually asking about. – Alexei Levenkov May 13 '20 at 17:52
  • 1
    Since you can't access the textboxes from the other thread, perhaps the method in the other thread should return the string back to the main thread, and then the main thread can modify the `Text` property. You could also reduce the code duplication by creating just a single method that takes in a `string filePath`. – Rufus L May 13 '20 at 17:53

2 Answers2

1

Yes, you can't share the form called in mainthread into a subthread.

You must use an Delegate to mainthread to update the textboxes.

READ: Invoke(Delegate)

Controls in Windows Forms are bound to a specific thread and are not thread safe. Therefore, if you are calling a control's method from a different thread, you must use one of the control's invoke methods to marshal the call to the proper thread. This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control.

You can also work with backgroundworker or async

Lulz
  • 32
  • 1
0

use "BeginInvoke" for update control value in Thread. like ...

 private void modifica1()
    {
        var read = File.ReadAllText(prim);
        read = read.ToUpper();
        File.WriteAllText(@"C:\Users\Wheelz\Desktop\Laborator09\fis1upper.txt", read);
this.BeginInvoke(new MethodInvoker(() =>
{ 
textBox1.Text = textBox1.Text.ToUpper();
}));
    }
    private void modifica2()
    {

        var read = File.ReadAllText(prim);
        read = read.ToUpper();
        File.WriteAllText(@"C:\Users\Wheelz\Desktop\Laborator09\fis2upper.txt", read);
        this.BeginInvoke(new MethodInvoker(() =>
{ 
textBox2.Text = textBox2.Text.ToUpper();
}));
    }