ThreadPool. This C# type manages a group of threads. With the ThreadPool class in .NET, we use threads and can incrementally update a ProgressBar.
WaitCallback note. The most important thing to know about ThreadPool is that we use the WaitCallback type. This is how we specify what code is run on a thread.
WaitCallback example. You can use WaitCallback by creating a new WaitCallback object with its constructor. Please pass this as the first argument to ThreadPool.QueueUserWorkItem.
Tip WaitCallback is a method called when the ThreadPool executes. It is a delegate that "calls back" its argument.
void Example()
{
// Hook up the ProcessFile method to the ThreadPool.// Note: 'a' is an argument name. Read more on arguments.
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), a);
}
private void ProcessFile(object a)
{
// I was hooked up to the ThreadPool by WaitCallback.
}
Parameters. You can use parameters by defining a special class for your important values. Then, the object is received by your method, and you can cast it.
Here We are sending 2 values to the ProcessFile threaded method. The object has contains the FileName and SelectedIndex.
// Special class that is an argument to the ThreadPool method.
class ThreadInfo
{
public string FileName { get; set; }
public int SelectedIndex { get; set; }
}
class Example
{
public Example()
{
// Declare a new argument object.
ThreadInfo threadInfo = new ThreadInfo();
threadInfo.FileName = "file.txt";
threadInfo.SelectedIndex = 3;
// Send the custom object to the threaded method.
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), threadInfo);
}
private void ProcessFile(object a)
{
// Constrain the number of worker threads// (Omitted here.)// We receive the threadInfo as an object.// ... Use the as-operator to cast it to ThreadInfo.
ThreadInfo threadInfo = a as ThreadInfo;
string fileName = threadInfo.FileName;
int index = threadInfo.SelectedIndex;
}
}
ProgressBar. You can use the ProgressBar by adding the Windows Forms control in the Toolbox panel on the right to your Windows program in the designer.
Note The Value is your position between the minimum and the maximum. Initialize your ProgressBar like this.
Tip The length of the colored part of your ProgressBar is the Value's percentage of the Maximum.
// Set progress bar length.// Here we have 6 units to complete, so that's the maximum.// Minimum usually starts at zero.
progressBar1.Maximum = 6; // or any number
progressBar1.Minimum = 0;
Invoke, ProgressBar. Here we use the Invoke method on the ProgressBar instance. We cannot access Windows controls on worker threads, as the UI thread is separate.
Detail We see the delegate UpdateBar declared. This delegate syntax indicates that you need to use the method as an object.
So We set the Maximum and Minimum on the ProgressBar. We invoke the delegate method after the work is completed to increment the size.
public partial class MainWindow : Form
{
// This is the delegate that runs on the UI thread to update the bar.
public delegate void BarDelegate();
public MainWindow()
{
InitializeComponent();
}
// When a button is pressed, launch a new thread.
private void button_Click(object sender, EventArgs e)
{
// Set progress bar length.
progressBar1.Maximum = 6;
progressBar1.Minimum = 0;
// Pass these values to the thread.
ThreadInfo threadInfo = new ThreadInfo();
threadInfo.FileName = "file.txt";
threadInfo.SelectedIndex = 3;
ThreadPool.QueueUserWorkItem(new WaitCallback(ProcessFile), threadInfo);
}
// What runs on a background thread.
private void ProcessFile(object a)
{
// (Omitted)// Do something important using 'a'.// Tell the UI we are done.
try
{
// Invoke the delegate on the form.
this.Invoke(new BarDelegate(UpdateBar));
}
catch
{
// Some problem occurred but we can recover.
}
}
// Update the graphical bar.
private void UpdateBar()
{
progressBar1.Value++;
if (progressBar1.Value == progressBar1.Maximum)
{
// We are finished and the progress bar is full.
}
}
}
Debugger. Once you have a program working, you can take these steps to visualize the threads. First, open your threaded app in debug mode.
And Once your application is running in the debugger, tell it to do its job and run the threads.
So Run the debugger with the green arrow and when the threads are running, hit the pause button in the toolbar.
Next steps. Please go to Debug, Windows, Threads. This menu item will open a window that shows exactly how many threads are running in the ThreadPool.
Counts. If you have a quad-core system, you may want at most 4 demanding threads. We can do this by keeping a count field and tracking the number of running threads.
Tip With this thread count field, you will need to use a lock in the C# language to avoid having the field incorrectly read or written.
Info We see that the method was asynchronously executed. It will not start its work until there are fewer than four other worker threads.
Detail You can use SetMinThreads on ThreadPool to improve the throughput and performance in bursts of activity.
A summary. We applied the ThreadPool class to effectively manage many threads. Progress bars and fast UIs on Windows Forms applications will improve user experience.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.