I have a Windows Forms application (not WPF) in which from the main form (UI thread) I am creating a separate thread to perform a long period of test execution. The idea is that the user starts the testing by clicking a button on the main form; when the user wants the testing to stop, the button on the main form is clicked again. This part works alright.
The main form is comprised of two tabs; a control tab containing file input boxes, radio buttons and the standard button used to start/stop the new thread. The second tab is a “log” tab which only contains a textbox.
What I am trying to do is update the textbox on the log tab (logText.Text) with progress while the second thread is running. I’ve searched the web and found what I thought would work; but I cannot get the expected results from it.
What I have done is to add the following to my forms class (frmMain.cs):

        void WriteToLogTab(string lineIn)
        {
            if (logText.InvokeRequired)
            {
                Action<String> tempDelegate = WriteToLogTab;
                logText.Invoke(tempDelegate);
            }
            else
            {
                logText.Text += lineIn;
            }
        }

And in the “worker class” (DoTesting.cs) I’ve added the following:

namespace PerpetualClientTest
{
    internal class DoUpgrades
    {
        frmMain callingForm = new frmMain();
…
…
…
        private void ProcessInput(string guid)
        {
            timeStamp = String.Format(DateTime.Now.ToString("MM/dd/yyyy H:mm:ss"));
            returnLog = String.Format("{0}: Rebooted {1}\r\n", timeStamp, guid);
            callingForm.WriteToLogTab(returnLog);
        }

The only way I can get the reference to callingForm.WriteToLogTab() to work is if I change the method in the forms class to Public (public void WriteToLogTab(string lineIn)) and even then it never updates logText.Text. When I step through the execution callingForm.WriteToLogTab is called, but when I enter that method it evaluates logText.InvokeRequired as false, going straight to the else segment.

Now, I know I’m missing something key and required here. Can anyone please let me know where I’ve gone wrong? I’m not very well versed in Threading or inter-thread communications; so a detailed example would be GREATLY appreciated!

Thanks for any help!

This behaviour is due to the fact that the form methods are executed inside the same thread, so no invoke is required.

The invoke will be required if the form is executed ina distinct thread than the method caller.

IE. Windows form application. The FormMain has a timer to show the date an time every second. The form is launched inside a main static class using FormMain.Show(). The static class continues to execute and uses an Application.Doevents() to allow the FormMain to show. At this moment, the static class is running in the thread 1, and the form in the thread 2.
In this situation, the invoke will be required.

Hope this helps.

This article has been dead for over six months. Start a new discussion instead.