0

I have a console application, that launches a form application (from another class) in a different thread.

But then, I wan't to access the richTextBox1 component from my main class, in the main thread and that throws an error wich says that I'm trying to access the component from another thread.

My code: (Form application)

public partial class ChatGui : Form
{
    public static RichTextBox textBox;
    public ChatGui()
    {
        InitializeComponent();
        richTextBox1.ReadOnly = true;
        richTextBox1.BackColor = SystemColors.Window;
    }

    public void WriteLine(string line)
    {
        richTextBox1.Text += line+"\r\n";
    }

    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            WriteLine("[You]: "+textBox1.Text);
            NetworkManager.SendPacket("rchat_msg " + textBox1.Text.Replace(" ", "%20"));
            textBox1.Text = "";
            e.Handled = true;
        }
    }

    public void Exit()
    {
        Application.Exit();
    }

    private void ChatGui_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;
    }

}

The main console application

public static void StartRemoteChat()
    {
        RemoteChat = true;
        Program.ChatGui = new ChatGui();
        new Thread(new ThreadStart(() =>
        {
            Application.Run(Program.ChatGui);
            while (RemoteChat)
            {
                // ...
            }
        })).Start();
    }

So, how can I access the richTextBox1 component from my main thread (I want to change some variables of the component) without this error happening ?

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Mine_Stone
  • 169
  • 3
  • 13

4 Answers4

3

The control is owned by the thread that creates it. In your case the thread that you start owns the form because it paints it so its going to be your forms ui thread.

However when you try to use another thread to make changes to the control, it will throw an exception just like you said. The way around this is to invoke the thread that created it to come and make the change that you want like this:

richTextBox1.BeginInvoke(new Action(()=>
{
// make changes to control here.
}));
Niklas
  • 955
  • 15
  • 29
0

one that can help you is the "CheckForIllegalCrossThreadCalls = false;" but used here(at the beginning):

public Form1()
    {
        InitializeComponent();
        CheckForIllegalCrossThreadCalls = false;            
    }

the advice is to use each call to "RichTextBox1" the invoke method. this method allows to interact with elements created by other threads. example:

richTextBox1.Invoke(new Action(() => richTextBox1.Text = "hello word"));

"CheckForIllegalCrossThreadCalls = false" is a solution that has enough dangers if it is used in complex programs. I hope I was helpful.

mnaro
  • 1
0

Simple call invoke to invoke the method from a new thread:

if (InvokeRequired)
{
     Invoke(new Action(**METHODHERE**));
     return;
}

and to pass parameters:

if (InvokeRequired)
{
     Invoke(new Action<string>(**METHODHERE**) **parameter**);
     return;
}

Good read: https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx

Cody J. Mathis
  • 652
  • 1
  • 9
  • 25
-2

try setting following property.

RichTextBox.CheckForIllegalCrossThreadCalls=false;

this may help you.

mayurb
  • 49
  • 1
  • 1
  • 6