Threading with Windows FormsWhere to set up Threads
Page 1 of 1
13 Replies - 1959 Views - Last Post: 23 June 2010 - 10:17 AM
#1
Threading with Windows Forms
Posted 21 June 2010 - 09:51 AM
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!
Replies To: Threading with Windows Forms
#2
Re: Threading with Windows Forms
Posted 21 June 2010 - 10:02 AM
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).
#3
Re: Threading with Windows Forms
Posted 21 June 2010 - 10:18 AM
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
#4
Re: Threading with Windows Forms
Posted 21 June 2010 - 10:50 AM
http://www.dreaminco...cation-in-c%23/
#5
Re: Threading with Windows Forms
Posted 21 June 2010 - 10:57 AM
This post has been edited by darkjohn20: 21 June 2010 - 11:00 AM
#6
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:08 AM
Global.Max_Clients = Convert.ToInt32(hMaxConnections.Text);
leads me to believe that it already deals with threading and multiple clients.
#7
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:11 AM
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
#8
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:18 AM
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
#9
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:33 AM
Quote
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.
#10
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:35 AM
Or do it by yourself (See the chat tutorial) and we will help you if you face any problems.
#11
Re: Threading with Windows Forms
Posted 21 June 2010 - 11:46 AM
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
#12
Re: Threading with Windows Forms
Posted 21 June 2010 - 03:25 PM
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
#13
Re: Threading with Windows Forms
Posted 21 June 2010 - 07:00 PM
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.
#14
Re: Threading with Windows Forms
Posted 23 June 2010 - 10:17 AM
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);
}
}
}
}
|
|

New Topic/Question
Reply




MultiQuote





|