I've created simple WindowsApplication project with one additional windwos form named Form2.

On default form I added button named button1.

And added this code

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;


namespace WindowsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public void button1_Click(object sender, EventArgs e)
        {
            noveforme nove = new noveforme(stvori);
            IAsyncResult r = nove.BeginInvoke(null, null);
            nove.EndInvoke(r);        
        }

        public delegate void noveforme();

        public void stvori()
        {
            Form2 f2 = new Form2();
            f2.Show();
        }
    }
}

I'm trying to run that new form on separate thread.

I expected first thread to freeze and to wait until second one ends......but the opposite happens. Second thread is frozen, and first isn't.

What am I doing wrong ?

Recommended Answers

All 4 Replies

The question just has to be asked..... Why are you invoking the second form this way ?

If your intent is to have the first form freeze and wait until the second form closes, then why not just show the second form as model using ShowDialog() ? That is the normal behaviour in windows applications.

Launching a second form from a thread has no advantage. When a form is launched in a windows application is stacks the form instances on the main application list of forms. This is how the windows dispatcher finds the form.

You can show many forms at once using show, all of them capable of accepting user interaction.
You can cause all forms to freeze by using ShowDialog on a form. When it exits, focus it brought back to the form that launched it.

If the Form is in another thread (yes you can do this... although not a good idea) then communicating with it has to be done through delegates to event handlers that will invoke into the owning thread. Alot more trouble than it is worth, since Windows can handle anything you need to do in the main thread. You can feed the second form from a thread easily enough, and is the main way programmers do it.

// Jerry

Tnx for your reply. :)

I'm just exploring language.

I'm aware of showdialog, and my intention wasn't to freeze first form, I foud it only strange that it didn't freeze. The same thing happens if I remove that EndInvoke line.


And in the end could you please explain how to create form on another thread.

I'm aware it will be big hassle to communicate with original thread, but it can't hurt....

big_B,

Okay, there are several ways to do it, so this example is but one of them.
I have two forms , first form has a button, second form has a timer, and two labels.
The one second timer simply posts the time to label1.
The second label is used to illustrate passing a string value from the main thread(or any other thread) to update its text.

// Form1
public partial class Form1 : Form
    {
        private Form2 f2 = null;
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (f2 != null)
                f2.setLabelText("Hello World");
            else
            {
                Thread x = new Thread(LoadF2);
                x.IsBackground = true;
                x.Start();
            }
        }

        delegate void f2Unloaded(object sender, FormClosedEventArgs e);
        void f2_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (button1.InvokeRequired)
            {
                f2Unloaded d = new f2Unloaded(f2_FormClosed);
                this.Invoke(d, new object[] { sender, e });
            }
            else
            {
                f2 = null;
            }
        }

        private void LoadF2()
        {
            f2 = new Form2();
            f2.FormClosed +=new FormClosedEventHandler(f2_FormClosed);
            f2.ShowDialog();
        }
    }

The button on form1 will either post text to form2 or start form2 in a new thread depending on if form2 is active.
If it is currently null (not active), then create a new thread, and call the LoadF2 method.
We have to know when the thread has released form2, so we assign an event handler to its FormClosed event.
It starts form2 as modal. This is important, because if you just show form2, then the thread will exit, automatically disposing all of its created objects (aka form2).

Because form2 is running in a thread, the event handler is also being called in the context of that thread, so we have to use a delegate to handle this event. I use the button to determine the InvokeRequired. There are other ways to check (iow no components on the form, or other thread), but this was right there so I use it. The InvokeRequired simply checks to see if this component is running in the thread that is making the call to the method or event handler.

public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.ToString("hh:mm:ss");
        }

        delegate void delegateShowLabel(string value);
        public void setLabelText(string value)
        {
            if (label2.InvokeRequired)
            {
                delegateShowLabel d = new delegateShowLabel(setLabelText);
                this.Invoke(d, new object[] {value});
            }
            else
                label2.Text = value;
        }
    }

Now when form1's button is pressed a second time, form2 is active, and we call form2's setLabelText method to update its label2 text property.
Again, we use a delegate to allow the (x) thread to handle the request ( "this" in this case is not the main thread, but rather is the thread that launched form2).


Hope this helps,
Jerry

PS: If this answers your question ,please mark the topic as solved.

tnx, much appreciated :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.