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
noteThe 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
exampleYou can use WaitCallback
by creating a new WaitCallback
object with its constructor. Please pass this as the first argument to ThreadPool.QueueUserWorkItem
.
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. }
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.
ProcessFile
threaded method. The object 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.
ProgressBar
like this.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;
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.
UpdateBar
declared. This delegate syntax indicates that you need to use the method as an object.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. } } }
Once you have a program working, you can take these steps to visualize the threads. First, open your threaded app in debug mode.
Please go to Debug, Windows, Threads. This menu item will open a window that shows exactly how many threads are running in the ThreadPool
.
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.
SetMinThreads
on ThreadPool
to improve the throughput and performance in bursts of activity.We applied the ThreadPool
class
to effectively manage many threads. Progress bars and fast UIs on Windows Forms applications will improve user experience.