0

I have simple Windows Form App in C# using VS 2019. When I run the application using F5, I face the exception

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

But when I use Ctrl+F5 everything works fine. Can anybody explain me why ?

Here is my code:

    private async void button1_Click(object sender, EventArgs e)
    {
      Task.Run(() =>
        {
            for (int i = 0; i < 500; i++)
            {
                Thread.Sleep(1000);
                richTextBox1.Text += string.Format("\n Row No: {0}", (i + 1));
            }
        });

       Task.Run(() =>
        {
            for (int i = 0; i < 500; i++)
            {
                Thread.Sleep(1000);
                richTextBox2.Text += string.Format("\n Row No: {0}", (i + 1));
            }
        });
    }
AliBagha
  • 3
  • 3

1 Answers1

3

When you use Ctrl+F5 you are starting without a debugger. The .net code does not throw the exception if the debugger is not attached.. However just because no error is thrown does not mean you should do it. It is still a bug in your code you should fix.

If you are curious the "correct way to do this" is not to use Task.Run and instead just use async methods.

private async void button1_Click(object sender, EventArgs e)
{
    Task task1 = UpdateTextBox1();
    Task task2 = UpdateTextBox2();

    await Task.WhenAll(task1, task2);
}

private async Task UpdateTextBox1()
{
    for (int i = 0; i < 500; i++)
    {
        await Task.Delay(1000);
        richTextBox1.Text += string.Format("\n Row No: {0}", (i + 1));
    }
});

private async Task UpdateTextBox2()
{
    for (int i = 0; i < 500; i++)
    {
        await Task.Delay(1000);
        richTextBox2.Text += string.Format("\n Row No: {0}", (i + 1));
    }
}
Scott Chamberlain
  • 124,994
  • 33
  • 282
  • 431
  • I checked your solution and I do not think same as you. By running the app using Ctrl+F5 the app works fine and nothing bad happens. And using the "await" just causes the second Task to start after finishing the first one. – AliBagha May 25 '20 at 07:08
  • @AliBagha, error still happens - values of richtextboxes will not be updated. – Fabio May 25 '20 at 07:13
  • @AliBagha You don't await your task. This means the exception is still thrown, but never evaluated an shown. However, it will at some time later suddenly pop up when the garbage collector frees the memory of the task. That's why you should always await tasks. – ckuri May 25 '20 at 07:13
  • 1
    "always await tasks" is a bit widespread. So why Multithreading don't always await a specific thread? Sometimes you have Threads where you don't know when they will be completed. In most cases you can, but not in every! So it's best practice to take care of exceptions in every thread. Here you should use invokation, THATS thread safe – TinoZ May 25 '20 at 07:17
  • @Fabio Actually, I just checked the source code, it only throws the error if a debugger is attached. Updated answer. – Scott Chamberlain May 25 '20 at 07:20