WinForm streaming management updates from other classes

Can someone please help me with the following problem:

There are two classes MainForm and LWriter. Below is the LWriter method, which, in addition to writing to a file, sends some updates to the RichTextBox control (via mainForm.UpdateLog (text)). Everything works fine, however this WriteOutput method also does some extensive processing, which freezes the form during calculation.

I think WriteOutput should be encapsulated in a separate thread. Can someone please help me explain how to put WriteOutput (LWriter class) in a thread that will then call mainForm.UpdateLog () from mainFrom in a safe way?

I am new to threads, so help would be greatly appreciated.

public void WriteOutput(string output, Links[] links) { try { using (StreamWriter sw = new StreamWriter(output)) { for (int x= 1; x<links.Length;x++) { ... sw.WriteLine( ... ); sw.Flush(); } mainForm.UpdateLog(<text>); } } catch(Exception e) { ... } } 
+4
source share
4 answers

delegate can be used for secure calls to Thread

Check out http://msdn.microsoft.com/en-us/library/ms171728.aspx

  // This delegate enables asynchronous calls for setting // the text property on a TextBox control. delegate void SetTextCallback(string text); // This method demonstrates a pattern for making thread-safe // calls on a Windows Forms control. // // If the calling thread is different from the thread that // created the TextBox control, this method creates a // SetTextCallback and calls itself asynchronously using the // Invoke method. // // If the calling thread is the same as the thread that created // the TextBox control, the Text property is set directly. private void SetText(string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } } 
+3
source

Usually you should run such lengthy operations in BackgroundWorker . Define a method of work:

 private void worker_DoWork(object sender, DoWorkEventArgs e) { // execute your WriteOutput method } 

and set is like a DoWork event DoWork :

 BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += new DoWorkEventHandler(worker_DoWork); worker.RunWorkerAsync(); // start the worker 

To safely update the user interface from another thread, use the Control.BeginInvoke method:

 mainForm.BeginInvoke( () => { mainForm.UpdateLog(<text>); }); 
+6
source

As suggested by Sonu, delegate can be used for streaming calls, and you can use Linq to shorten the code:

 this.BeginInvoke( (Action) delegate () { //code to update UI }); 

See this link for more details.

+2
source

Interaction with user interface controls must be performed in the user interface thread. You can build a string in the background thread, but you must use Control.Invoke or Control.BeginInvoke to marshal the UI thread before interacting with it.

Lots of examples of this are network and stack overflows.

+1
source

Source: https://habr.com/ru/post/1390291/


All Articles