DotNet Threaded Fibonacci Series Printing
In this article we will be learning to create a threaded application that prints the fibonacci series in a worker thread. The first step is to create a form as shown in the screenshot below:

- Start Index - This denotes the index in which the series should start.
- Length - This denotes the number of elements that should be generated in the series.
- Start Button - Clicking this button will start generating the series.
- Pause Button - Clicking this button will pause the series generation.
- Stop Button - Clicking this button will stop the series generation.
#region Usings using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Windows.Forms; #endregion namespace Fibonacci { public class Worker { #region Delegates private delegate void AppendTextDelegate(string text); private delegate void EnableButtonsDelegate(bool started); #endregion #region Private Variables private Thread _thread = null; // Don't make the thread wait on _event.Set() private readonly ManualResetEvent _event = new ManualResetEvent(true); private bool paused = false; #endregion #region Public Properties public frmMain MainForm { get; set; } public RichTextBox TextBoxControl { get; set; } public bool IsAlive { get; set; } #endregion #region Constructor public Worker() { _thread = new Thread(Work); } #endregion #region Public Methods public void Start(Parameters parameters) { // Start parameterized thread IsAlive = true; _thread.Start(parameters); } public void Pause() { if (paused) { // Resume Thread _event.Set(); } else { // Pause Thread _event.Reset(); } paused = !paused; } public void Stop() { // Abort thread IsAlive = false; _thread.Abort(); } #endregion #region Private Methods private void Work(object parameters) { // Retrieve the first and second parameters double? first = ((Parameters)parameters).First ?? 0; double? second = ((Parameters)parameters).Second; if (second != null) { // If the second parameter (length) is specified // loop until the length is reached double length = 0; double? i = first; while (length < second) { PrintSeries(i); i++; length++; } } else { // If the second parameter (length) is not specified // loop indefinitely double? i = first; while (true) { PrintSeries(i); i++; } } // The thread has ended. Therefore, reset button states MainForm.Invoke(new EnableButtonsDelegate( MainForm.EnableButtons), false); } private void PrintSeries(double? i) { // Wait if the thread is paused. _event.WaitOne(); // Generate the Fibonacci series double result = Fibonacci(i); // Display the result to the user TextBoxControl.Invoke(new AppendTextDelegate( MainForm.AppendText), result.ToString()); // Wait for 1 second Thread.Sleep(500); } private static double Fibonacci(double? n) { double previous = 0; double next = 1; // Logic to calculate the Fibonacci series. for (double i = 0; i < n; i++) { double temp = previous; previous = next; next = temp + next; } return previous; } #endregion } }The above code uses a parameterized Thread.Start function that accepts the Start Index and Length for calculating the Fibonacci Series. Here's the form code to instantiate and run the thread.
#region Usings using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; #endregion namespace Fibonacci { public partial class frmMain : Form { #region Private Variables private Worker _worker = null; #endregion #region Constructor public frmMain() { InitializeComponent(); } #endregion #region Events private void frmMain_Load(object sender, EventArgs e) { // Set default button states EnableButtons(false); } private void btnStart_Click(object sender, EventArgs e) { // Reset results textbox txtResults.Text = string.Empty; // Set parameters Parameters parameters = new Parameters { First = ParseDouble(txtFirst), Second = ParseDouble(txtSecond) }; // Create and start the worker thread that generates the Fibonacci series _worker = new Worker() { MainForm = this, TextBoxControl = txtResults }; _worker.Start(parameters); // Disable start button and enable pause / stop buttons EnableButtons(true); } private void btnPauseResume_Click(object sender, EventArgs e) { // Pause or Resume the thread _worker.Pause(); // Change the text in the button control btnPauseResume.Text = btnPauseResume.Text.Equals("Pause") ? "Resume" : "Pause"; } private void btnStop_Click(object sender, EventArgs e) { // Abort the thread _worker.Stop(); // Enable start button and disable pause / stop buttons EnableButtons(false); } private void frmMain_FormClosing(object sender, FormClosingEventArgs e) { // Check to see if the thread is running and stop it before closing // the form. This would prevent any errors during form close if (_worker == null) return; if (_worker.IsAlive) { _worker.Stop(); } } #endregion #region Private Methods private static double? ParseDouble(TextBox textBox) { // Parse the text box input double param = 0; return (Double.TryParse(textBox.Text, out param)) ? (double?)param : null; } #endregion #region Public Methods public void AppendText(string text) { // Display the Fibonacci series to the user txtResults.Text += text + Environment.NewLine; txtResults.Select(txtResults.Text.Length - 1, 0); txtResults.ScrollToCaret(); } public void EnableButtons(bool started) { // Set button states based on action btnStart.Enabled = !(started); btnStop.Enabled = started; btnPauseResume.Enabled = started; } #endregion } }Here's the code for the Parameter class.
#region Usings using System; using System.Collections.Generic; using System.Linq; using System.Text; #endregion namespace Fibonacci { public class Parameters { #region Public Properties public double? First { get; set; } public double? Second { get; set; } #endregion } }Try this program and see the results for yourself. If you have any questions, feel free to raise them in our .NET Forum.