Results 1 to 1 of 1
-
18th Jun 2010, 12:07 AM #1OPლ(ಠ益ಠლ)Website's:
extremecoderz.com[c#] Multi-Threading and keeping the GUI useable.
In this tutorial we will be using multiple threads (multi-threading) and showing the benefits of doing so, and also the impracticalities.
We are going to create a small form containing a button, a progressbar and a label, and use these objects to display the output of intensive work, whilst still maintaining a useable GUI that does not lock-up as a result of the hard work.
This one is a toughie to explain. I hope I managed to explain it clearly enough.
Again, its fully useable, you can copy/paste it right in.
PHP Code: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;
namespace WindowsFormsApplication4
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// Here we declare that "StatusInfo" will be our delegated void to use in our thread.
// We also declare 3 required variables: status, progress, and MaxProgress.
// We are declaring it here, so all "voids" can make use of it, not just the "void"
// it was created in.
private delegate void StatusInfo(string status, int progress, int MaxProgress);
private void Form1_Load(object sender, EventArgs e)
{
// Set the form size
this.Size = new Size(340, 150);
CreateSomeObjects();
}
private void CreateSomeObjects()
{
// Button - myButton1
Button Button1 = new Button(); // Declare a new button, and give it a unique ID
Button1.Name = "myButton1"; // Give it a name (we will be using this later)
Button1.Size = new Size(100, 23); // Set the size
Button1.Location = new Point(10, 10); // Set the location on the form
Button1.Text = "Click Me"; // Set the text for the button
Button1.Click += new EventHandler(letsPlay); // Set the click event (what to execute when clicked)
// ProgressBar - myProgress1
ProgressBar ProgressBar1 = new ProgressBar();
ProgressBar1.Name = "myProgress1";
ProgressBar1.Size = new Size(300, 23);
ProgressBar1.Location = new Point(10, 43);
ProgressBar1.Minimum = 0; // The minimum value of the progressbar
ProgressBar1.Maximum = 100; // The maximum Value of the progressbar
ProgressBar1.Value = 0; // The current position of the progressbar
// Label - myLabel1
Label Label1 = new Label();
Label1.Name = "myLabel1";
Label1.AutoSize = true;
Label1.Location = new Point(10, 76);
Label1.Text = "Ready.";
// Draw the objects on the current Form (this)
this.Controls.Add(Button1);
this.Controls.Add(ProgressBar1);
this.Controls.Add(Label1);
}
private void letsPlay(object sender, EventArgs e)
{
// Here we get interesting. We create a new seperate thread, seperate from the main thread.
// We are doing this because we dont want our GUI to lock-up whilst processing this
// heavy loop (simulated by making the thread sleep).
// So here we declare the new thread, and tell it to execute "MoveProgress".
System.Threading.Thread myThread = new System.Threading.Thread(MoveProgress);
// Kickoff time :D - go go go!
myThread.Start();
}
private void MoveProgress()
{
// We are going to set our delegated void as a NEW delegate, and that it should look to
// "DisplayStatus" to pass the values. The void "DisplayStatus" will have the same required
// variables that we described at the beginning: status, progress, and MaxProgress.
StatusInfo StatusInfo = new StatusInfo(DisplayStatus);
// Ok - so lets simulate some heave work by forcing this thread to sleep for 50 milliseconds
// after every loop.
// Notice the use of a StringBuilder. Its no use here really, and TERRIBLE practice to put
// it in the loop like i have, but for the sake of learning, you can easily see how to
// use a StringBuilder, and obviously, how it could be of use in large applications.
// NOTE: You can "Append" to the existing data, or "AppendLine" to add a new line of data.
for (int i = 0; i < 101; i++)
{
StringBuilder sb = new StringBuilder(); // Declare a new instance of a stringBuilder called sb
sb.Append("Loading: "); // Append to the existing text (currently zero-length)
sb.Append(i); // and again...
sb.Append(" of 100"); // and again
// Finally we get to the point where we need to "output" this information we have obtained.
// In our example we are going to use both a ProgressBar and a label to do so.
// So we "Invoke" the forum. Kinda like an "oi, something needs to be done, wake up" call.
// We are Invoking the delegate StatusInfo, and passing the required variables as declared
// When we made the instance of it at the beginning: status, progress, and MaxProgress.
// So, we use the contents of the stringBuilder "sb" for the status, and convert it to a
// string (because currently its a StringBuilder, not a string)
// And for this example we will pass the integer i as the progress, with a maximum of 100.
Invoke(StatusInfo, sb.ToString(), i, 100);
System.Threading.Thread.Sleep(50);
}
}
private void DisplayStatus(string status, int progress, int maxProgress)
{
// The following code is VERY interesting and useful.
// When we created our objects (button, ProgressBar and label) - we did so without the use
// of the designer. This means when the form loads, nothing is there. The objects are created
// AFTER the form loads. So, if we try to modify one of its properties in this code, its not
// going to be visible. So we need to find these controls and again assign them a unique ID
// so we can manipulate them for our required purposes; displaying our output.
ProgressBar myFoundProgressBar = new ProgressBar();
Label myFoundLabel = new Label();
foreach (Control myControl in this.Controls) // foreach control in my form
{
if (myControl.Name == "myProgress1") // if the controls name is "myProgress1"
myFoundProgressBar = (ProgressBar)myControl; // Then assign it to the ID "myFoundProgressBar"
if (myControl.Name == "myLabel1") // We do the same here for the label.
myFoundLabel = (Label)myControl;
}
// Now we are able to manipulate these controls using the data we obtained when we invoked it.
myFoundLabel.Text = status;
myFoundProgressBar.Maximum = maxProgress;
myFoundProgressBar.Value = progress;
}
// OK. so we need to understand something here. Why invoke? Why use a seperate thread? It seems like
// a whole bunch of hard work, just to display an output!
// Well. There is one important factor:
// You cannot manipulate an object using a thread IF THAT THREAD DID NOT CREATE THE OBJECT.
// And its right. The thread myThread DID NOT create the button or anything else for that matter.
// The PRIMARY thread did.
// So, to get around this, we "invoke". This basically allows you to pass variables back to the
// Primary thread, where everything was created in the first place, and thus manipulate the controls,
// Whilst still being able to throw the hard work in a seperate thread, and thus not lock-up the main
// thread (which is home to the GUI)
// So what does this all mean? It means that your GUI will not lock up, because a secondary thread,
// NOT the primary thread is doing all the work, and every now and again, you invoke the primary thread
// to update the GUI.
}
}
jayfella Reviewed by jayfella on . [c#] Multi-Threading and keeping the GUI useable. In this tutorial we will be using multiple threads (multi-threading) and showing the benefits of doing so, and also the impracticalities. We are going to create a small form containing a button, a progressbar and a label, and use these objects to display the output of intensive work, whilst still maintaining a useable GUI that does not lock-up as a result of the hard work. This one is a toughie to explain. I hope I managed to explain it clearly enough. Again, its fully useable, you can Rating: 5
Sponsored Links
Thread Information
Users Browsing this Thread
There are currently 1 users browsing this thread. (0 members and 1 guests)
Similar Threads
-
What's Keeping You On XP?
By Daniel in forum News & Current EventsReplies: 17Last Post: 4th Jan 2012, 03:40 AM -
Keeping up with kardashians
By EnCiPh3r in forum General DiscussionReplies: 10Last Post: 27th Oct 2011, 03:34 PM -
[C#] Difference with Invoke and Threading
By litewarez in forum Web Development AreaReplies: 5Last Post: 13th Jul 2010, 04:53 PM -
[PHP] Threading Class
By SplitIce in forum Tutorials and GuidesReplies: 8Last Post: 1st Oct 2009, 01:24 AM -
Can't load XP without keeping XP CD in CDROM
By swapnil0545 in forum Technical Help Desk SupportReplies: 9Last Post: 21st Apr 2009, 04:07 PM
themaPoster - post to forums and...
Version 5.22 released. Open older version (or...