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);
}
}
- See project on GitHub at https://github.com/vdkkia/Using-Multi-Core
Comments
Post a Comment