I want to log in to RichTextBox, but during long operations the form hangs.

I tried to call in a separate task, but an error occurs that accessing the RichTextBox from another thread is not possible.

How to get out of this situation?

  • And how was the stream applied? I have an example on VB.Net with log output in the textbox using a timer. Need to? - Ella Svetlaya
  • I hung up on the button of the callback factor call method, and at the end called wait. - iluxa1810
  • Give a piece of code and error text. Somehow the base used this solution - vedu.ru/programming/?cont=articles&articles_id=1100 - Ella Svetlaya
  • UI elements do not like working with other threads. You need a broker who is in the UI thread and receives messages from other threads. - rdorn
  • @rdorn, can you give examples? The scenario is such, there is a button that calls a method that does something for a long time and writes to the UI. - iluxa1810 pm

1 answer 1

Elements UI do not like to work with other threads, and should not. Therefore, you must either use ready-made components to implement inter-thread communication, or implement it explicitly.

I do not see a deep sense in copying official documentation on ready-made components, see the code examples by reference. All references are on MSDN.

1. Native WinForms Solution - use the BackgroundWorker component: description , examples , tutorial

2. You can also use Dispatcher , even though it belongs to WPF. Description .

The choice of option is in my opinion a matter of taste, but I have not very practical experience in this, I may be mistaken.

3. BeginInvoke is another option for accessing methods between threads. The code will look like this:

 using System; using System.Threading; using System.Windows.Forms; public partial class Form1 : Form { public Form1() { InitializeComponent(); Task.Run(new Action(TestThreading)); AddText("Same thread"); } void TestThreading() { Thread.Sleep(2000); AddText("Async change"); } public void AddText(string text) { if (this.textBox1.InvokeRequired) { Action<string> updaterdelegate = new Action<string>(AddText); try { this.Invoke(updaterdelegate, new object[] { text }); } catch (ObjectDisposedException ex) { } } else { textBox1.Text = text; } } } 

an idea from here , but there is an error that I have already corrected, you can copy-paste, not forgetting to throw on the TextBox form, it will also work with any other UI elements and any of their properties. But if there are a lot of threads, do not forget to place locks on the record.

  • @rdom, and in 3 example, nothing extra needs to be done? Hung on the button 'Task.Run (() => excl.Create ());' and the thread ends immediately. Should I probably hang something on the button to wait for the end of the thread? - iluxa1810
  • What for? UI in theory should not wait for anyone. The task flow is one thing, the UI flow is another. The only thing that needs to be done is to hang up the form waiting for the completion of child threads or force them to close when closing - rdorn
  • @rdom, and how correctly to make so that the task would not "die" at an exit from the button where this task is created? - iluxa1810
  • @rdom, probably, it is worth creating some List <>, which will store tasks? - iluxa1810
  • @ iluxa1810 is better to issue a separate issue. Yes, and I need to get to the computer, from the phone it is only convenient to read - rdorn