logo

.NET Article

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:

Wafy Fibonacci threaded form
  • 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.
The next step is to create a Worker thread class. Refer to the code given below:
#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.

STUDENT TESTIMONIALS

Copyright © 2011 Wafy Technologies Pvt. Ltd. All rights reserved.
Use of this website signifies your agreement to the Terms of Use and Online Privacy Policy. Valid CSS! Valid XHTML 1.0 Transitional Website Content Protection