Threading with Windows Forms

Where to set up Threads

Page 1 of 1

13 Replies - 2669 Views - Last Post: 23 June 2010 - 10:17 AM Rate Topic: -----

#1 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Threading with Windows Forms

Posted 21 June 2010 - 09:51 AM

Alright, so I'm making a simple Chat Client and Server using Windows Forms.
I have created the forms and set them up to successfully create a Server and Client.

The relative files are Program.cs and Form1.cs.

In Form1.cs I have the actions to read the input boxes and then create the server and all of that.
In Program.cs, I have only the defaults for a Windows Form App, including the running of my form.

After reading countless tutorials and topics on threading, I just can't figure out where, and in which file, to create threads.
I need to create a thread that would act as a main loop while the server/client is running, and deal with Packet Sending/Receiving and updating the GUI.

Also, what are delegates? Are they needed? What do they do?

Thanks!

Is This A Good Question/Topic? 0
  • +

Replies To: Threading with Windows Forms

#2 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Threading with Windows Forms

Posted 21 June 2010 - 10:02 AM

Updating the GUI has to be done on the GUI thread, so if your other threads need to update the GUI you'll be using Invoke() to get it done.

Threads: Generally you'll have a loop that is waiting for connections from clients. When it gets one, that's where you create a new thread and pass the connection to that thread so you can go back to waiting for connections. This is a good example of a simple client/server.

A delegate, in this case, is used to handle asynchronos calls. You tell the system 'when this is done/happens, I want this method to run'. The methods that you use to handle button presses on your GUI are delegates (as an example).
Was This Post Helpful? 0
  • +
  • -

#3 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 10:18 AM

For the networking portion of code, I am using the library found here: http://www.darknetworking.net/.

Here is the relevant code for the start/stop buttons of my GUI:
private void hStartServer_Click(object sender, EventArgs e)
{
    int Instances = 1;
    int Threads = 0;
    Global.Max_Clients = Convert.ToInt32(hMaxConnections.Text);
    ushort Local_Port = Convert.ToUInt16(hPort.Text);
    string Local_IP = hIPAddress.Text.ToString();
    //string ExternalIP = new System.Net.WebClient().DownloadString("http://www.whatismyip.com/automation/n09230945.asp");
    Global.SendPacket = mn.CreatePacket();
    Global.RecvPacket = mn.CreatePacket();

    mn.SetMemorySize(Global.SendPacket, 1024);
    mn.Start(Instances, Threads);
    mn.SetLocal(0, Local_IP, Local_Port, Local_IP, Local_Port);
    mn.DisableUDP(0);
    int Result = mn.StartServer(0, Global.Max_Clients, 0, 0);            

    if (Result == 0)
    {
        hStatus.Text = "Online";
        hStartServer.Enabled = false;
        hStopServer.Enabled = true;
        hIPAddress.ReadOnly = true;
        hPort.ReadOnly = true;
        hMaxConnections.ReadOnly = true;
        hStopServer.Focus();
        //hMainLoop.Start();
        //The main loop should start here. Currently hMainLoop is a timer...
    }
}

private void hStopServer_Click(object sender, EventArgs e)
{
    mn.Finish(-1);
    hStatus.Text = "Offline";
    hStartServer.Enabled = true;
    hStopServer.Enabled = false;
    hIPAddress.ReadOnly = false;
    hPort.ReadOnly = false;
    hMaxConnections.ReadOnly = false;
    hStartServer.Focus();
    hMainLoop.Stop();
}



Unfortunately I don't think I can redistribute the library, but there isn't any need to since I know perfectly well how to use it. The only thing I can't figure out is where, and in which file, to put thread code. I'm also not quite sure what this code should be, since I'm new to threads.

Any help is appreciated. If I'm not explaining well enough, let me know please.

Thanks.

This post has been edited by darkjohn20: 21 June 2010 - 10:33 AM

Was This Post Helpful? 0
  • +
  • -

#4 eclipsed4utoo  Icon User is offline

  • Not Your Ordinary Programmer
  • member icon

Reputation: 1524
  • View blog
  • Posts: 5,957
  • Joined: 21-March 08

Re: Threading with Windows Forms

Posted 21 June 2010 - 10:50 AM

here is a tutorial that PsychoCoder wrote on doing a Client/Server Chat application.

http://www.dreaminco...cation-in-c%23/
Was This Post Helpful? 0
  • +
  • -

#5 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 10:57 AM

I read that already, perhaps I'll take another look.

This post has been edited by darkjohn20: 21 June 2010 - 11:00 AM

Was This Post Helpful? 0
  • +
  • -

#6 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:08 AM

Without being able to see the library you are using, this line:
Global.Max_Clients = Convert.ToInt32(hMaxConnections.Text);
leads me to believe that it already deals with threading and multiple clients.
Was This Post Helpful? 0
  • +
  • -

#7 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:11 AM

I defined that under Program.cs:

using System;
using System.Collections.Generic;
using System.Windows.Forms;
//using System.Threading;

namespace WindowsForm
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new tServer());
        }
    }
    public class Global
    {
        public static int Max_Clients;
        public static long SendPacket;
        public static long RecvPacket;
    }
}


because that was the solution I found when searching Google for creating global variables.
Also, Here is a quote from the site:

"Multi-threaded:
Internally DarkNet receiving is multi-threaded in order to make use of all available cores on the system."

The main problem I'm facing is continually checking for clients and sending/receiving packets. I tried using a timer, but someone said that a while-loop in a thread would be a better idea?

This post has been edited by darkjohn20: 21 June 2010 - 11:15 AM

Was This Post Helpful? 0
  • +
  • -

#8 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:18 AM

So, for example, my main loop should be:

private void hMainLoop_Tick(object sender, EventArgs e)
        {
            //const int OP_CLIENT_JOINED = 0;
            //const int OP_CLIENT_LEFT = 1;
            const int OP_REQUEST_NAME = 2;

            int Joined = mn.ClientJoined(0);
            if (Joined > 0)
            {
                Console.WriteLine("Client " + Joined + " has joined!");
                mn.AddInt(Global.SendPacket, OP_REQUEST_NAME);
                int Send = mn.SendTCP(0, Global.SendPacket, Joined, false, false);
            }

            int Left = mn.ClientLeft(0);
            if (Left > 0)
            {
                Console.WriteLine("Client " + Left + " has left!");
            }

            for (int Client = 1; Client <= Global.Max_Clients; Client++)
            {
                // Console.WriteLine(Client.ToString());
                int TCP_Packets = mn.RecvTCP(0, Global.RecvPacket, Client);

                if (TCP_Packets > 0)
                {
                    Console.WriteLine("# of TCP Packets: " + TCP_Packets.ToString());
                    int OPERATION = mn.GetInt(Global.RecvPacket);

                    switch (OPERATION)
                    {
                        case (OP_REQUEST_NAME):
                            string Name = mn.GetString(Global.RecvPacket, 0, true);
                            Console.WriteLine("Client " + Client.ToString() + "'s name is " + Name);
                            break;
                    }
                }
            }
        }



but I would prefer it not to be in a timer, unless I SHOULD use a timer? I just thought that a constant while-loop would run smoother, and if the action completed before my 100ms tickrate, it would start again instead of having a set interval.

This post has been edited by darkjohn20: 21 June 2010 - 11:19 AM

Was This Post Helpful? 0
  • +
  • -

#9 Momerath  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1010
  • View blog
  • Posts: 2,444
  • Joined: 04-October 09

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:33 AM

From the documentation on their page (which isn't very good, IMHO):

Quote

mnStartServer
This initializes an instance to server state and is used to begin hosting.

Parameters
int Instance: This is the instance that the command should use.


int Maximum_number_of_clients: This is the maximum number of clients that can be connected at any one time. Clients attempting to connect when the maximum has been reached will be rejected and mnConnect/mnPollConnect will return -2. Client IDs range from 1 to the maximum number of clients.


It handles the threading for you.
Was This Post Helpful? 0
  • +
  • -

#10 elbielefeld  Icon User is offline

  • D.I.C Head

Reputation: 70
  • View blog
  • Posts: 216
  • Joined: 18-May 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:35 AM

Thats right, but we don't know how the darknetworking library works. Maybe this is done internally and an event is thrown when a new connection request or data arrives. So ask the developer of the library or check to samples he provides to see how it works.
Or do it by yourself (See the chat tutorial) and we will help you if you face any problems.
Was This Post Helpful? 0
  • +
  • -

#11 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 11:46 AM

I guess the part I'm confused on is:

To know when a client connects/disconnects, and when information is received, you have to have the following (or something similar) in a loop:
int Joined = mn.ClientJoined(0);
if (Joined > 0)
{
    //Client with ID stored in Joined has joined.
}

int Left = mn.ClientLeft(0);
if (Left > 0)
{
    //Client with ID stored in Left has left.
}

for (int Client = 1; Client <= Global.Max_Clients; Client++)
{
    int TCP_Packets = mn.RecvTCP(0, Global.RecvPacket, Client);

    if (TCP_Packets > 0)
    {
        //There is a TCP packet waiting to be read.
    }
}



My question is, how to I run this loop ALONG WITH my GUI, so that it could display info like "# of Clients Connected" and other data.
I guess the best way to explain it would be:

The library handles all of the multi-threaded events, but I have to manually ask it what these events are.
So, even though the program may be sending/receiving data by itself, I don't know that data until I ask.
How can I constantly ask while maintaining a GUI, without my process hanging or anything.

@elbielefeld: No event is called as far as I know, you just have to manually ask how many packets are waiting.
Here is an example WITHOUT a GUI. Does this help you understand any? http://www.darknetwo...es/Instances.cs

This post has been edited by darkjohn20: 21 June 2010 - 11:53 AM

Was This Post Helpful? 0
  • +
  • -

#12 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 21 June 2010 - 03:25 PM

I'm going to post the structure of my code. If someone could tell me what I'm doing wrong I would be grateful.

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 WindowsForm
{
    public partial class Server : Form
    {
        public Server()
        {
            InitializeComponent();
        }

        private void hStartServer_Click(object sender, EventArgs e)
        {
            //Server creation code. If successful then:
            ThreadStart MainThread = new ThreadStart(MyThread);
            Thread LoopThread = new Thread(MainThread);
            LoopThread.IsBackground = true;
            LoopThread.Start();
        }

        private void hStopServer_Click(object sender, EventArgs e)
        {
            // LoopThread.Abort(); doesn't work. It doesn't know what LoopThread is.
        }

        public void MyThread()
        {
            while (true)
            {
                //My main loop code
                Thread.Sleep(100);
            }
        }
    }
}



How can I stop the thread when I press the "Stop" button. If I stop the thread, can I start it back up with no problems?

This post has been edited by darkjohn20: 21 June 2010 - 03:25 PM

Was This Post Helpful? 0
  • +
  • -

#13 JackOfAllTrades  Icon User is offline

  • Saucy!
  • member icon

Reputation: 6036
  • View blog
  • Posts: 23,432
  • Joined: 23-August 08

Re: Threading with Windows Forms

Posted 21 June 2010 - 07:00 PM

The two variables you create in here
private void hStartServer_Click(object sender, EventArgs e)
{
    //Server creation code. If successful then:
    ThreadStart MainThread = new ThreadStart(MyThread);
    Thread LoopThread = new Thread(MainThread);
    LoopThread.IsBackground = true;
    LoopThread.Start();
}



are only visible inside that event handler. The LoopThread variable needs to be a member of the class. This e-book is a very good C# threading resources, as is this site.
Was This Post Helpful? 1
  • +
  • -

#14 darkjohn20  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 33
  • Joined: 21-June 10

Re: Threading with Windows Forms

Posted 23 June 2010 - 10:17 AM

Solved:

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 Server
{
    public partial class Server : Form
    {
        bool running = false;

        public Server()
        {
            InitializeComponent();
        }

        private void hStart_Click(object sender, EventArgs e)
        {
            running = true;
            ThreadStart MainLoop = new ThreadStart(MainThread);
            Thread Thread = new Thread(MainLoop);
            Thread.IsBackground = true;
            Thread.Start();
        }

        private void hStop_Click(object sender, EventArgs e)
        {
            running = false;
        }

        public void MainThread()
        {
            while (running == true)
            {
                Thread.Sleep(100);
            }
        }
    }
}


Was This Post Helpful? 0
  • +
  • -

Page 1 of 1