I am trying to do very intensive work with the database in the project. Here's a walkthrough:
We need to look for our database of workers, we call Locums and find it for a specific job. This procedure begins when we decide to process the x number of jobs. Thus, with the click of a button, we process the ProcessJobBatch() method. However, this method is only processed with a very limited number of Locums. Therefore, it takes less than 10 seconds to populate the scheduler manager. Now that a limited number of Locums is served, we need to run a background job to check out the rest of Locums. There are about 1250 of them!
So, once ProcessJobBatch() , and BackgroundWorker , BackgroundWorkerMoreLocums disabled. Now this worker basically performs a simple cycle: go through all 1250 employees for each job. It takes too long. I need to plan this using an alternative strategy that I cannot use at the ATM, or I need to show a secondary progress indicator for the internal cycle for each.
Details Explanation: We import a batch of tasks (from 10 to 70) on a daily basis daily. As soon as the package is imported, the application indicates to the logged in user "Preference to find" those newly created tasks. The user already has a list of his favorite places (from 1 to 20). First, he wants to distribute the work among his favorites. This is done through ProcessJobBatch() . But there are two scenarios that prevent the flow there and then:
- What if certain jobs don't fall in any favorite locus?
- What to do if in general there is a DB slogan that can carry out almost all tasks, but since it is not a favorite?
So, I am finishing the job mapping scenario with each Locum.
Question: Can a second BackgroundWorker work inside a BackgroundWorker DoWork? Am I doing a second scan incorrectly?
Environment: 64-bit version of Windows 7 Pro, Visual Studio 2010, C #, .NET 4.0 and Windows Forms
private void ButtonPreferenceFind_Click(object sender, EventArgs e) { if (LookUpBatches.EditValue != null) { JobBatch JobBatchSelected = DbContext.JobBatches.FirstOrDefault(job_batch=> job_batch.OID == LookUpBatches.EditValue.ToString()); if (JobBatchSelected != null && JobBatchSelected.Jobs.Count(condition => condition.JobStatusID == 1) > 0) { if (XtraMessageBox.Show(String.Format("Are you sure to process {0} job(s)?", JobBatchSelected.Jobs.Count(condition => condition.JobStatusID == 1)), Text, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { ProcessJobBatch(JobBatchSelected); IEnumerable<Job> SpecificJobs = from req_jobs in JobBatchSelected.Jobs where req_jobs.JobStatusID == 1 select req_jobs; ProgressBarControlPreferenceFinder.EditValue = 0; ProgressBarControlPreferenceFinder.Properties.Minimum = 0; ProgressBarControlPreferenceFinder.Properties.Maximum = SpecificJobs.Count() - 1; BackgroundWorkerMoreLocums.RunWorkerAsync(SpecificJobs); } else { LookUpBatches.Focus(); } } else { XtraMessageBox.Show("Unable to retrieve the selected batch or the batch has no processable jobs.", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); LookUpBatches.Focus(); } } else { XtraMessageBox.Show("Select a batch first.", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); LookUpBatches.Focus(); } } #region Background Searching private void BackgroundWorkerMoreLocums_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { try { e.Result = GetTableData(e.Argument); } catch (Exception ex) { XtraMessageBox.Show("Background Error: " + ex.Message, "Excite Engine 2", MessageBoxButtons.OK, MessageBoxIcon.Error); e.Result = ex; } } private void BackgroundWorkerMoreLocums_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) { // only display progress, do not assign it to grid ProgressBarControlPreferenceFinder.Increment(e.ProgressPercentage); } private void BackgroundWorkerMoreLocums_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { if (e.Result is DataTable) { //dataGridView1.DataSource = e.Result as DataTable; } else if (e.Result is Exception) { } } private DataTable GetTableData(Object JobList) { DataTable ResultDataTable = new DataTable(); ResultDataTable.Columns.Add(); IEnumerable<Job> JobBatchSelected = (IEnumerable<Job>)JobList; IEnumerable<Locum> LeftOverLocums = from lefties in DbContext.Locums //where SchedulerMatrixStorage.Resources.Items.Select(res => (long)res.Id).ToList().Contains(lefties.OID) == false select lefties; int NumOfJobsProcessed = 0; List<KeyValuePair<long, TemporaryPreferenceFindLocum>> AlreadyPrefferedLocums = new List<KeyValuePair<long, TemporaryPreferenceFindLocum>>(); foreach (Job oneJob in JobBatchSelected) { foreach (Locum oneLocum in LeftOverLocums) { if (DbContext.Availabilities.Any(check => check.LocumID == oneLocum.OID && check.AvailableDate == oneJob.JobDate && check.AvailabilityStatusID == 1)) { //This Locum can do this job //Now check if he/she has been just alloted if (AlreadyPrefferedLocums.Any(search => search.Key == oneLocum.OID && search.Value.JobDate == oneJob.JobDate) == false) { //No? Cool! //Add to the list to prevent double allocation AlreadyPrefferedLocums.Add(new KeyValuePair<long, TemporaryPreferenceFindLocum>(oneJob.OID, new TemporaryPreferenceFindLocum(oneJob.JobDate, oneJob.OID, oneLocum.OID, oneLocum.FirstName + " " + oneLocum.LastName))); } else { continue; } } else { //Not marked as Avaliable on the required job date... continue; } } NumOfJobsProcessed++; BackgroundWorkerMoreLocums.ReportProgress((int)(NumOfJobsProcessed * 100F / (JobBatchSelected.Count() - 1))); } return ResultDataTable; } #endregion