Работа с backgroundWorker
Чтобы выполнение запроса не грузило прогу, запихиваю его в backgroundWorker:
{
this.backgroundWorker1.RunWorkerAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
worker.ReportProgress(0,"Working...");
e.Result = ExecQuery(worker,e);
}
private DataTable ExecQuery(BackgroundWorker worker, DoWorkEventArgs e)
{
//пользователь отменил выполнение
if (worker.CancellationPending)
{
e.Cancel = true;
return null;
}
else
{
DataTable dtQueryRes = new DataTable();
daQuery.Fill(dtQueryRes);
worker.ReportProgress(100, "Complete.");
return (dtQueryRes);
}
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message, " Error");
}
else if (e.Cancelled)
{
this.StatusDesc.Text = "Canceled";
}
else
{
//привязка данных к гриду и т.д.
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
this.StatusProgress.Value = e.ProgressPercentage;
this.StatusDesc.Text = e.UserState.ToString();
}
private void btnStop_Click(object sender, EventArgs e)
{
this.backgroundWorker1.CancelAsync();
this.StatusDesc.Text = "Canceled";
this.btnStop.Visible = false;
}
Проблема возникает когда пользователь пытается остановить работу Воркера. Визуально вроде всё останавливается, а на деле св-во IsBusy Воркера всё ещё установлено в trrue и повторный запуск Воркера не возможен. :(
Во время работы фонового процесса нужно периодически проверять свойство CancellationPending. Сам воркер не остановится - из него приходится выходить самому.
А как из него выйти самостоятельно?
Головой думать пробовали прежде чем нажимать кнопку "Ответить"?
Когда воркер выполняет запрос к БД
остановить его работу невозможно, даже если ежесекундно проверять состояние CancellationPeding и устанавливать
e.Cancel = true.
Можно ли как-то очистить поток воркера независимо от того, закончил он свою работу или нет?
Нет. В принципе можно конструировать отдельный поток (используя класс Thread) и вызывать у него Abort-метод. Исполнение Fill() будет скорее всего прервано, но за целостность датасета после таких манипуляций никто не ручается.
При вызове Abort статус потока ThreadState меняется на AbortRequested и работа потока не прекращается...
Можно ли как-то очистить поток не дожидаясь окончания его работы?
Поток не очищается. Поток останавливается. Что вам мешает просто забыть об этом потоке?
Просто когда пользователь остановит выполнение запроса (а поток по сути не остановится) и запустит новый запрос, возникают проблемы.
Можно ограничить количество одновременных запросов, скажем 3я активными потоками.
Спасибо, буду пробовать )