Click here to Skip to main content
15,887,896 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
I am trying to build a solution that will allow a thread to update WinForm properties (TextBox) while processing data in the background. I've put together a "sample" project that starts a thread to update the WinForm while the main program runs.

Here is the main Form Class:

C#
namespace Thread_Test_Sending_Data_to_Thread_Function
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            int i;
            InitializeComponent();
            FormData FormData1 = new FormData();
            Thread1 MyThread = new Thread1();

 
            for (i=0; i<10; i++)
            {
                FormData1.Label1Data = i;
                FormData1.Label1Data = i * 10;

                Thread WriteScreen = new Thread(delegate ()
                {
                    MyThread.FormWriteMethod(FormData1);
                });

                WriteScreen.Start();
                Thread.Sleep(1000);
            }
           
        }

and here is the thread class

C#
namespace Thread_Test_Sending_Data_to_Thread_Function
{
    public class Thread1 : Form1
    {
        private delegate void SetLabelTextDelegate(FormData InputClass);
        public void FormWriteMethod(FormData InputClass)
        {
            if (TestLabel1.InvokeRequired)
            {
                TestLabel1.BeginInvoke(new SetLabelTextDelegate(FormWriteMethod), new object[] { InputClass });
                return;
            }
            TestLabel1.Text = InputClass.Label1Data.ToString();
            TestLabel2.Text = InputClass.Label2Data.ToString();
        }
    }
}

Everything builds OK. I believe I've set this up to allow me to send a reference to the FormData class to the thread. FormData is loaded by the main form program which then causes the thread to be executed. It pauses for the thread to complete and then updates the FormData. The Thread has inherited Form1 so it should have access to the TestLable1 TextBox defined in Form1

When I try to run the program the program gets to the statement Thread1 MyThread = new Thread(); and then loops back to the beginning of the program until a stack overflow occurs. I must be missing something simple. Any suggestions?

What I have tried:

I've looked at numerous examples of how to send data to a thread and how to access the WinForm data from the thread. From what I have found, what I am doing seems to be correct. Not sure what to try next.
Posted
Updated 13-Nov-16 7:11am
Comments
Mehdi Gholam 13-Nov-16 10:40am    
Why threads?

Simple:
C#
public Form1()
{
    int i;
    InitializeComponent();
    FormData FormData1 = new FormData();
    Thread1 MyThread = new Thread1();

And
C#
public class Thread1 : Form1

Because Thread1 is derived from Form1, when you construct a new Thread1 instance, the Form1 constructor is called, which creates a Thread1 instance, which calls it's own Form1 constructor, which creates as Thread1 instance, which calls ...

At some point the system runs out of stack memory to hold all it's return addresses and your app crashes.
 
Share this answer
 
There are soooo many things wrong in here I don't know where to start.

But, I'll tell you that it throws a stack overflow because Form1 is creating an instance of Thread1. Thread1 inherits from Form1, which creates an instance of Thread1, which inherits from Form1, which creates an instace of Thread1, which inherits from Form1, which creates an instance of Thread1, which inherits from Form1, which creates an instance of Thread1, ... get the idea yet? This is what's running the stack out.

I have no idea why you've got Thread1 inheriting from Form1 at all. The delegate and methods to update the label should be on Form1.

The work you've got running on Form1 should be somewhere else. I don't know, like Thread1?

You've got LabelData1 being set by two consecutive lines, which won't do anything useful at all. The first value will never be painted on screen because the UI thread will still be hung up running the code that's setting LabelData1 to i*10.

This is way overcomplicated with code in all the wrong classes.
 
Share this answer
 
Comments
Midi_Mick 13-Nov-16 11:21am    
I think, looking at the code, that the 2nd assignation of Label1Data is just a typo - should be Label2Data.
Otherwise, all comments good. However, if he removes the inheritance of Thread1 from Form1, and corrects the typo, I think it might actually work as he expects. Not pretty, but working. He might also need to put an Application.DoEvents() call after the Sleep to get the updates displaying at the appropriate intervals, rather than all happening at the end.
Dave Kreskowiak 13-Nov-16 12:02pm    
Application.DoEvents is a shortcut for horrible practice. NEVER recommend using it, ever.
Bug here, you store 2 values in same object.
C#
FormData1.Label1Data = i;
FormData1.Label1Data = i * 10;

You can as well remove the first line.

I don't know what you have in mind, but you are in a loop and this value is the only way for 2 thread to distinguish from each other, but since it is an object and that the value is continuously changing, it defeat the idea of giving a number to each thread. Are you making threads that race against each others ?
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900