Using Multi-Core to process heavy tasks by using Background Worker (C#)


It is essential to apply multi cores of CPU when you use long tasks in C#, because running such tasks in main body of application causes the process to be executed in same thread as UI thread and practically the user can’t use the application. For avoid these problem, we can use BackgroundWorker in Visual Studio Form based application. Subroutines and functions that are called in BackgroundWorkers’ DoWork event, will run in a thread apart from UI thread, So the user can continue using the application.
Sometimes it is needed to use more BackgroundWorkers in order to speed up executing heavy tasks.
An important point to consider in order to use BackgroundWorkers is that how to form the functions to be executable in the Worker’s body.
Another important point when using multiple Workers, is splitting the functions and assigning them to the Workers that is the most important part of work.

For example, following code is used to handle long lasting functions and heavy tasks (in my case sorting, removing duplicates, … of text Data).

 //Firstly define 4 arrays of .txt files that will be processed
        FileInfo[] firstArray;
        FileInfo[] secondArray;
        FileInfo[] thirdArray;
        FileInfo[] forthArray;

 void AssignTasks()
        {
            #region SORT
                      
           label1.Text = "(1/5) Sorting, removing duplicates and place mean value for duplicates...";
          
            //Creating Output directory
            DirectoryInfo Dir = new DirectoryInfo(SourcePath.Text);
            Directory.CreateDirectory(SourcePath.Text + @"\Sorted");
            int TotalFiles = Dir.GetFiles().Length;
            if (TotalFiles % 5 != 0)
            error.Visible = true;
                
            //Splitting all files into 4 part to assign to Workers by Array 'Take' and 'Skip'
            FileInfo[] FI = Dir.GetFiles();

            FileInfo[] temp1 = FI.Take(FI.Length / 2).ToArray();
            FileInfo[] temp2 = FI.Skip(FI.Length / 2).ToArray();

            firstArray = temp1.Take(temp1.Length / 2).ToArray();
            secondArray = temp1.Skip(temp1.Length / 2).ToArray();
            thirdArray = temp2.Take(temp2.Length / 2).ToArray();
            forthArray = temp2.Skip(temp2.Length / 2).ToArray();

            //Running Workers
            SortWorker1.RunWorkerAsync(firstArray);
            SortWorker2.RunWorkerAsync(secondArray);
            SortWorker3.RunWorkerAsync(thirdArray);
            SortWorker4.RunWorkerAsync(forthArray);
                   
            #endregion

        }

 private void SortWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            int Counter = 0;
            int TotalFiles = (e.Argument as FileInfo[]).Length;
            foreach (FileInfo fi in e.Argument as FileInfo[])
            {
                Counter++;
                if (fi.Extension == ".txt")
                {
                    //Some Heavy tasks
                }
                SortWorker1.ReportProgress((Counter * 100) / TotalFiles);
            }
        }

// After all workers finish their job, running another task using one worker
        private void SortWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (!SortWorker2.IsBusy && !SortWorker3.IsBusy && !SortWorker4.IsBusy && !backgroundWorker1.IsBusy)
            {
                backgroundWorker1.RunWorkerAsync(SourcePath.Text);
            }
        }




Comments