I'm Keyvan Nayyeri, a 25 years old Ph.D. student at
the Computer Science department of
the University of Texas at San Antonio.
I'm also
a Software Architect and Developer and previously held a B.Sc.
degree in Applied Mathematics.
This is my blog where I publish content about various topics specifically Programming Languages and Compilers, Software
Engineering and Programming.
Recently I've been working on a dynamic Windows Application written with Visual Basic to iterate through a huge list of different servers at different locations and upload and download some files to or from them automatically. This applications runs automatically every night to move data to a center and send updated data back to clients.
To connect to the remote servers I used a component that was connecting via an asynchronous operation. It means that your code execution can follow while this operation isn't finished yet.
The problem was here because I was iterating through a list of servers to connect to them and perform upload and download tasks but when my application had finished the loop, it was just trying to connect to the first server! I also was unable to connect to multiple servers at once so had to solve this problem somehow.
For a simple application this could be easy but this application is very complex example of threading and I was loosing my mind in various threads. Today I decided to write a very simple prototype of the main threading mechanism for the application then extend it and add other pieces to this prototype to solve the issue.
Fortunately result was very good and could help me solve the problem. Since it may be helpful for others, I share it here as well. The main part of the prototype is what I share here.
The problem is we want to run a sequence of several tasks one by one with .NET threading with a simple constraint: a task can't start unless the previous task finishes successfully.
Before following the discussion suppose that I have a Windows Forms application with a single form that includes a Button and a StatusStrip control. When user clicks on the button, application iterates from 1 to 10, creates a new thread and tries to update the status text with the name of current thread and waits for a few seconds. After finishing the loop, it finally shows an output text in a MessageBox. This output text contains a list of thread names and the corresponding times when thread has reached to the last line of the method.
The below code shows this in action:
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 ThreadingSample
{
public partial class frmMain : Form
{
private string output;
public frmMain()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
Exec();
MessageBox.Show(this.output, "Result");
}
private void Exec()
{
for (int i = 1; i < 11; i++)
{
ThreadStart start = new ThreadStart(Iterate);
Thread internalThread = new Thread(start);
internalThread.Name = i.ToString();
internalThread.Priority = ThreadPriority.Highest;
internalThread.IsBackground = true;
internalThread.Start();
}
}
private void Iterate()
{
Thread thisThread = Thread.CurrentThread;
toolStripStatusLabel.Text = string.Format
("Current Thread Name: {0}", thisThread.Name);
// Wait, wait, wait
Thread.Sleep(3000);
// Go!
this.output += string.Format("Thread Name: {0} - Time: {1} \n",
thisThread.Name, DateTime.Now.ToString("hh:mm:ss"));
}
}
}
You shouldn't like the output because it quickly finishes the execution and displays an empty MessageBox.

Can you guess what's the reason? When program creates a new thread on each iteration and follows its execution in Iterate method, it doesn't wait for the Iterate method to finish and suddenly moves to the next iteration with a new thread! This is the nature of the threading! So all the threads arrive to Iterate method with a few milliseconds difference and as execution hasn't reached to the last line of this method, it can't add anything to output. This takes a few seconds but UI thread reaches to the call to MessageBox before then.
But what's the solution? The solution is very simple and is actually a single line of code. You need to use Thread.Join method in order to wait for the current thread to finish execution then follow the execution of program. In my case, code had become so complex that I couldn't find this simple point and this is the reason that we have prototyping as a good technique!
The updated code that uses Thread.Join to solve the problem is here. I also added a few lines of code to move the execution to Exec with a delegate to create a critical region.
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 ThreadingSample
{
public partial class frmMain : Form
{
private string output;
private delegate void ExecDelegate();
public frmMain()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
Thread.BeginCriticalRegion();
ExecDelegate del = new ExecDelegate(Exec);
del.DynamicInvoke(null);
Thread.EndCriticalRegion();
MessageBox.Show(this.output, "Result");
}
private void Exec()
{
for (int i = 1; i < 11; i++)
{
ThreadStart start = new ThreadStart(Iterate);
Thread internalThread = new Thread(start);
internalThread.Name = i.ToString();
internalThread.Priority = ThreadPriority.Highest;
internalThread.IsBackground = true;
internalThread.Start();
// It doesn't jump here quickly :-D
internalThread.Join();
}
}
private void Iterate()
{
Thread thisThread = Thread.CurrentThread;
toolStripStatusLabel.Text = string.Format
("Current Thread Name: {0}", thisThread.Name);
// Wait, wait, wait
Thread.Sleep(3000);
// Go!
this.output += string.Format("Thread Name: {0} - Time: {1} \n",
thisThread.Name, DateTime.Now.ToString("hh:mm:ss"));
}
}
}
The output of this code is beautiful. It counts the thread names in the status and finally shows a MessageBox that contains the execution time of each thread.

You can download the source code for this sample from here.
Eber Irigoyen
Dec 18, 2007 9:46 PM
#
what about using a ThreadPool?
http://msdn2.microsoft.com/en-us/library/3dasc8as(VS.80).aspx
Keyvan Nayyeri
Dec 19, 2007 8:16 AM
#
Yep, That could be as well but IMO this approach is simpler and easier to implemen.
Amin
Dec 19, 2007 3:01 PM
#
Thanks Keyvan, with this approach you helped me!
carl » Samsung D900
Aug 14, 2008 8:40 AM
#
Pingback from carl » Samsung D900
Leave a Comment