Link to home
Start Free TrialLog in
Avatar of Valleriani
VallerianiFlag for Sweden

asked on

C# 2010: Threading, Delegates -- Form 'locking up' when trying to Show form!

Hello,

I am using C#.NET 2010, but I'm having an issue.  I have tried to simplify the coding into a basic application that does it.

What's happening is I have a thread, and then I try to show another form within that thread when certain objectives have been met (isClicked == true).. The problem is, when the form tries to display Form2, Form2 is in a locked up state where I can't move the window. I've attached the basic coding, you'll need a simple Form1 and Form2 as well.

I believe I need something called 'Delegates', but I am not sure how to use it, and I fully don't understand it so far and how it works. The goal is to simply display Form2 with no freezes while being run in the thread.

Any suggestions or tips?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    static class Program
    {
        public static Form2 m_ChildForm;
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

Open in new window

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

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private Thread Messages;
        private bool isConnected;
        private bool isClicked = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Program.m_ChildForm = new Form2();
            isConnected = true;
            Messages = new Thread(new ThreadStart(this.Communication));
            Messages.Start();
        }

        private void Communication()
        {
            while (isConnected == true)
            {
                if (isClicked == true)
                {
                    Program.m_ChildForm.Show();
                    isClicked = false;
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            isClicked = true;
        }
    }
}

Open in new window

Avatar of Carlos Villegas
Carlos Villegas
Flag of United States of America image

Hello, you specific problem is this:
private void Communication()
{
    while (isConnected == true)
    {
        if (isClicked == true)
        {
            Program.m_ChildForm.Show();
            isClicked = false;
        }
    }
}

Open in new window

This loop dont let the windows messages be processed, so you can do this to allow the messages queue be processed:
private void Communication()
{
    while (isConnected == true)
    {
        if (isClicked == true)
        {
            Program.m_ChildForm.Show();
            isClicked = false;
        }
        Application.DoEvents();
    }
}

But you need to check your design, for what you want  to use that loop?
And sorry for my poor english...
Avatar of Valleriani

ASKER

Overall whats happening is i'm waiting for the client to connect and get a OK message, when it gets a OK, it will show the form.  Communication() was meant to be hooked up with sockets, and processes messages received from the server.
Hrm that doesn't work either unless I'm always running DoEvents, so something seems to be not working yet.

If Doevents is called, it loads but then it locks up again unless I keep calling DoEvents
Yes, but that is not the correct way, I will give you an example....
SOLUTION
Avatar of Carlos Villegas
Carlos Villegas
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Avatar of Mike Tomlinson
Mike Tomlinson
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Both solutions worked but I found the work from Idle_Mind was a bit better in the end as it didn't require much editing of my current coding. when I used ShowDialog(), it did load the form, but it didn't display anything as it should. Using:

        public void ShowChildForm()
        {
            if (this.InvokeRequired)
            {
                this.Invoke((MethodInvoker)(delegate() { ShowChildForm(); }));
            }
            else
            {
                if (Program.m_ChildForm == null || Program.m_ChildForm.IsDisposed)
                {
                    Program.m_ChildForm = new MainChat(this);
                }
                Program.m_ChildForm.Show();
            }
        }

I was able to use the global m_ChildForm in all locations, including in the thread.

Though both did work in there examples though, in my actual coding it was Idle_Minds' coding who seemed to handle my full current source with minimal changes.

Thanks both!