Thread-safe updates of a WinForm control from other classes

前端 未结 4 1000
不思量自难忘°
不思量自难忘° 2021-01-13 15:20

Could someone please help me with the following problem:

There are two classes MainForm and LWriter. Below is a method from the LWriter that in addition to writing

相关标签:
4条回答
  • 2021-01-13 16:04

    Interactions with UI controls must be done on the UI thread. You can build the string on a background thread, but you should use Control.Invoke or Control.BeginInvoke to marshal to the UI thread before interacting with it.

    Lots of examples of this on the net and stack overflow.

    0 讨论(0)
  • 2021-01-13 16:09

    delegate can be used for Thread safe calls

    Check this 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;
            }
        }
    
    0 讨论(0)
  • 2021-01-13 16:15

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

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

    See this link for more information.

    0 讨论(0)
  • 2021-01-13 16:24

    Typically you should run this kind of time-consuming operations in a BackgroundWorker. Define a work method:

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

    and set is as the DoWork event handler:

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

    To safely update the UI from a different thread use the Control.BeginInvoke method:

    mainForm.BeginInvoke(
       () => { mainForm.UpdateLog(<text>); });
    
    0 讨论(0)
提交回复
热议问题