Во-первых, я знаю, что должен использовать надлежащие методы обработки потоков (Threadpool, BeginInvoke и т. д.), чтобы выполнить это, но в настоящее время это немного выше моего понимания, и мне потребуется некоторое время, чтобы прочитать материал и понять это (если у вас есть какие-либо URL-ссылки на мой сценарий, пожалуйста, опубликуйте их).
Тем временем я использую backgroundWorker для извлечения очень большого набора результатов и заполнения им DatagridView. Я успешно создаю SortableBindingList<TEntities>
в своем событии DoWork и передаю его в результате. И в событии RunWorkerCompleted
я разыгрываю и привязываю это SortableBindingList<TEntities>
к своей сетке. Мои 2 основные области беспокойства заключаются в следующем:
1) Доступ к закрытым переменным. Я хочу передать один из двух параметров List<long>
в свое событие DoWork
, но запустить другой запрос в зависимости от того, какой список ему был передан. Я могу обойти это, объявив частную логическую переменную на уровне класса, которая действует как своего рода флаг. Это кажется глупым спрашивать, но в моем DoWork
можно ли мне получить доступ к этой частной переменной и соответствующим образом направить запрос? (Я проверил это, и это работает, без каких-либо ошибок)
private bool SearchEngaged = false;
private void bgw_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker worker = sender as BackgroundWorker;
e.Result = GetTasks((List<long>)e.Argument, worker, e);
}
SortableBindingList<Task> GetTasks(List<long> argsList, BackgroundWorker worker, DoWorkEventArgs e) {
SortableBindingList<Task> sbl = null;
if (worker.CancellationPending) {
e.Cancel = true;
}
else {
if (SearchEngaged) {
sbl = DU.GetTasksByKeys(argsList);
}
else {
sbl = DU.GetTasksByDivision(argsList);
}
}
return sbl;
}
2) Поток пользовательского интерфейса зависает в начале RunWorkerCompleted. Хорошо, я знаю, что мой пользовательский интерфейс реагирует во время события DoWork
, потому что требуется +/- 2 секунды для запуска и возврата моего SortableBindingList<Task>
, если я не привязывайте список к сетке, а просто заполняйте его. Однако мой пользовательский интерфейс зависает, когда я привязываю его к сетке, что я делаю в событии RunWorkerCompleted
. Имейте в виду, что моя сетка имеет 4 столбца изображений, которые я обрабатываю в CellFormatting
. Этот процесс занимает еще 8 секунд, в течение которых мой пользовательский интерфейс полностью неинтерактивен. Я знаю о последствиях этого для нескольких потоков, но есть ли способ выполнить заполнение и форматирование Grid в фоновом режиме или без зависания пользовательского интерфейса? RunWorkeCompleted выглядит так:
private void bgw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Cancelled) {
lblStatus.Text = "Operation was cancelled";
}
else if (e.Error != null) {
lblStatus.Text = string.Format("Error: {0}", e.Error.Message);
}
else {
SortableBindingList<Task> sblResult = (SortableBindingList<Task>)e.Result;
dgv.DataSource = sblResult;
dgv.Enabled = true;
TimeSpan Duration = DateTime.Now.TimeOfDay - DurationStart;
lblStatus.Text = string.Format("Displaying {0} {1}", sblResult.Count, "Tasks");
lblDuration.Visible = true;
lblDuration.Text = string.Format("(data retrieved in {0} seconds)", Math.Round(Duration.TotalSeconds, 2));
cmdAsyncCancel.Visible = false;
tmrProgressUpdate.Stop();
tmrProgressUpdate.Enabled = false;
pbStatus.Visible = false;
}
}
Извините за длинный вопрос, но я буду очень признателен за ваши ответы! спасибо!