/// <summary>
        /// Default class constructor.
        /// </summary>
        /// <param name="mapPointer">Object related to file map.</param>
        /// <param name="refStart">Scanner start index.</param>
        /// <param name="refLength">Length of the scanning session.</param>
        /// <param name="threadNo">Thread ID related to this scan session.</param>
        /// <param name="threadCnt">Object related to thread control class.</param>
        public HashProcessor(List <DataStuctInfo> mapPointer, int refStart, int refLength, int threadNo, ThreadControl threadCnt)
        {
            _fileMap      = mapPointer;
            _scanStartPos = refStart;
            _scanEnd      = refLength + _scanStartPos;
            _threadId     = threadNo;
            _threadCntrl  = threadCnt;

            OnMatchFound += OnUpdateUi;
        }
        private void btnStartScan_Click(object sender, EventArgs e)
        {
            try
            {
                InitScanProcess();

                _outputFile = txtOutputFile.Text.Trim();
                string scanDir     = txtScanDirectory.Text.Trim();
                int    scanThreads = Convert.ToInt32(numUpDownScanThreads.Value);

                UpdateStatusMessage(@"Validating input data and initializing...");

                //Check if the selected scan directory is still available.
                if (!Directory.Exists(scanDir))
                {
                    showValidatationMessage(@"Unable to find scan directory", MessageBoxIcon.Warning);
                    return;
                }

                lstBoxResults.Items.Clear();

                _scanList = new List <DataStuctInfo>();
                UpdateStatusMessage(@"Scanning directory contents...");

                String[] fileList = Directory.GetFiles(scanDir, "*", SearchOption.AllDirectories);

                _totalFilesToScan = fileList.Length;

                //Check if the files to scan is greater than the number of allocated threads.
                if (_totalFilesToScan < scanThreads)
                {
                    showValidatationMessage(@"Total files found in the directory is less than the scan thrad count. Please reduce the thread count or select a different direcotory.", MessageBoxIcon.Warning);
                    return;
                }

                foreach (string filePath in fileList)
                {
                    _scanList.Add(new DataStuctInfo(filePath));
                }

                if (_scanList.Count < 2)
                {
                    showValidatationMessage(@"Selected directory may not contain enough files to perform matching", MessageBoxIcon.Warning);
                    return;
                }

                Invalidate();

                if (File.Exists(_outputFile))
                {
                    File.Delete(_outputFile);
                }

                UpdateStatusMessage(@"Start scanning files...");

                btnStartScan.Enabled        = false;
                btnPause.Enabled            = true;
                btnPause.Visible            = true;
                btnCancel.Enabled           = true;
                btnCancel.Visible           = true;
                btnSelectDirectory.Enabled  = false;
                btnSelectOutputFile.Enabled = false;

                _threadExecState = new ThreadControl
                {
                    ThreadPause = false
                };

                UpdatePauseCaption();
                Refresh();

                OutputList = new BlockingCollection <OutputDataStruct>();
                PerformFileHashUpdate(scanThreads);
            }
            catch (Exception ex)
            {
                result = ShowThreadExceptionDialog("Error occured.", ex);
                // Exits the program when the user clicks Abort.
                if (result == DialogResult.Abort)
                {
                    Environment.Exit(0);
                }
            }
        }