See it. You must first read the data that is in the controls in the UI stream. And then send them to another thread. Now it is common to use Task to execute code in a separate thread. Thus, your code will look like this:
// UI-поток string text = textbox.Text; Task.Run(() => ProcessText(text)); // метод ProcessText будет выполнен в пуле потоков
What to do if the stream is already there, and you need to deliver a message to it? In any case, for this, some message loop must run in the stream. WinForms doesn’t have a convenient message loop, but you can borrow from WPF. To do this, connect the build WindowsBase , and start a dispatcher.
using System.Windows.Threading; // ... Dispatcher dispatcher = null; // запускаем поток var t = new Thread(ThreadProc); t.SetApartmentState(ApartmentState.STA); t.Start(); void ThreadProc() { Debug.WriteLine("bg thread started"); dispatcher = Dispatcher.CurrentDispatcher; Dispatcher.Run(); Debug.WriteLine("bg thread finished"); }
Now you can deliver messages to this thread:
string text = textBox.Text; dispatcher.BeginInvoke((Action)(() => ProcessInThread(text)));
When a thread is no longer needed, you can close it:
dispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
Okay, access to the dispatcher variable should be synchronized in a good way. I do not do this in order not to burden the code.