Я пытаюсь выполнить очень интенсивную работу с БД в проекте. Вот краткий обзор:
Нам нужно найти в нашей базе данных работников, которую мы назвали Locums, и найти одну для конкретной работы. Эта процедура начинается, когда мы решаем обработать х количество заданий. Итак, одним нажатием кнопки мы обрабатываем, используя метод ProcessJobBatch()
. Однако этот метод обрабатывает только очень ограниченное количество Locums. Таким образом, заполнение элемента управления планировщика занимает менее 10 секунд. Теперь, когда обслуживается ограниченное количество Locums, нам нужно запустить фоновое задание, чтобы проверить остальные Locums. Их около 1250!
Итак, как только ProcessJobBatch()
закончится, BackgroundWorker
, BackgroundWorkerMoreLocums
исчезнет. Теперь этот работник в основном выполняет простой цикл: для каждой работы нужно пройти всего 1250 сотрудников. Это занимает слишком много времени. Мне нужно спланировать это, используя альтернативную стратегию, которую я не могу использовать в банкоматах, или мне нужно показать дополнительный индикатор выполнения для внутреннего цикла for-each.
Подробнее Объяснение: Мы импортируем партию рабочих мест (от 10 до 70) несколько раз в день. Как только пакет импортирован, приложение инструктирует вошедшего в систему пользователя «Поиск предпочтений» для вновь созданных заданий. У пользователя уже есть список его любимых локаций (от 1 до 20). Он хочет сначала распределить работу среди своих любимцев. Это делается через ProcessJobBatch()
. Но есть два сценария, которые мешают потоку тут же:
- Что если определенные рабочие места не упали
Любой любимый язык?
- Что если в целом есть место обитания?
БД, которая может делать почти все работы, но
так как он не любимый?
Итак, я получаю сценарий соответствия задания каждому Locum.
Вопрос:
Может ли второй BackgroundWorker работать в DoWork BackgroundWorker?
Я делаю второе сканирование неправильно?
Среда: 64-разрядная версия Windows 7 Pro, Visual Studio 2010, C #, .NET 4.0 и 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