Cześć.
Mam problem z zatrzymywaniem zdarzenia w backgroundworkerze, które wykonuje się na bazie danych dłuższy czas. Dodalem komentarz w kodzie co chcialbym moc zatrzymywac w kazdym momencie, ponieważ bywa tak ze zapiszDGV() może się wykonywać dość długo, w zależności od przekazanego zapytania. Nie wiem natomiast jak to obsłużyć? Wątki to póki co trochę czarna magia, poza najprostszym - backgroundworkerem - który jest dość łatwy w implementacji i obsłudze (jak dla mnie...).
Program będzie miał docelowo wykonywać takie pobieranie i zapisywanie w pętli, więc dodatkowo jakby ktoś mógł mi podpowiedzieć jak w m_oBackgroundWorker_DoWork wymusić aby jedno zadanie czekało drugie? Ponieważ też zauważyłem, że jeśli zapiszDGV() trwa nieco dłużej, to wychodzi ze statusem "Pobranie niepomyslne" i przechodzi do następnej iteracji.
Kod wygląda mniej więcej tak:
funkcja wykonujaca zapytanie do bazy -
public void datgs(out string textbox, string zapytanie, ref DataTable table, OdbcConnection conn, OdbcDataAdapter dadapter)
{
try
{
conn.Open();
dadapter = new OdbcDataAdapter(zapytanie, conn);
table = new DataTable();
dadapter.Fill(table);
textbox = "Pobranie pomyslnie" + "\n";
}
catch
{
textbox = "Pobranie niepomyslnie" + "\n";
}
finally
{
//zapytanie = "";
conn.Close();
}
}
public void zapiszDGV() //laduje tabele do dataGridView2
{
try
{
dataGS.datgs(out zdarzenie, zapytanie, ref table2, conn, dadapter);
dataGridView2.DataSource = table2;
zapytanie = "";
}
catch
{
zdarzenie = "Pobranie niepomyslne" + "\n";
}
}
wywolanie backgroundworkera i jego obsluzenie -
private void button1_Click(object sender, EventArgs e)
{
ilosc_zapytan = 0;
if (null == m_oBackgroundWorker)
{
m_oBackgroundWorker = new BackgroundWorker();
m_oBackgroundWorker.DoWork += new DoWorkEventHandler(m_oBackgroundWorker_DoWork);
m_oBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_oBackgroundWorker_RunWorkerCompleted);
m_oBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(m_oBackgroundWorker_ProgressChanged);
m_oBackgroundWorker.WorkerReportsProgress = true;
m_oBackgroundWorker.WorkerSupportsCancellation = true;
}
zapytanie = "";
m_oBackgroundWorker.RunWorkerAsync();
}
void m_oBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) //wykonuje zadanie w drugim wątku
{
//Thread.Sleep(500);
if (ilosc_zapytan == 0)
{
if (m_oBackgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
//break;
}
//pobranie sql
pobierzSQL.pobierzSQL(out zdarzenie, ref zapytanie, ilosc_zapytan, combobox, conn);
m_oBackgroundWorker.ReportProgress(i++);
//pobranie sciezki
pobierzSciezke.pobierzSciezke(out zdarzenie, conn, ilosc_zapytan, ref sciezka, ref nazwa_pliku, combobox, zapytanie);
m_oBackgroundWorker.ReportProgress(i++);
//ladowanie DGV
zapiszDGV(); //<== to chcialbym moc zatrzymywac w kazdym momencie
m_oBackgroundWorker.ReportProgress(i++);
//zapis raportu
zapiszRaport();
m_oBackgroundWorker.ReportProgress(i++);
i = 0;
}
else
{
while (ilosc_zapytan > 0)
{
if (m_oBackgroundWorker.CancellationPending)
{
e.Cancel = true;
break;
}
//pobranie sql
pobierzSQL.pobierzSQL(out zdarzenie, ref zapytanie, ilosc_zapytan, combobox, conn);
m_oBackgroundWorker.ReportProgress(i++);
//pobranie sciezki
pobierzSciezke.pobierzSciezke(out zdarzenie, conn, ilosc_zapytan, ref sciezka, ref nazwa_pliku, combobox, zapytanie);
m_oBackgroundWorker.ReportProgress(i++);
//ladowanie DGV
zapiszDGV(); //<= jesli trwa dluzej to przechodzi ze statusem "Pobranie niepomyslne" i przechodzi do następnej iteracji
m_oBackgroundWorker.ReportProgress(i++);
//zapis raportu
zapiszRaport();
m_oBackgroundWorker.ReportProgress(i++);
ilosc_zapytan--;
}
i = 0;
ilosc_zapytan = 0;
}
}
void m_oBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) //pobiera informacje o zdarzeniach z 2 watku i wypluwa je do richTextBoxa1
{
AppendLog(zdarzenie);
}
void m_oBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
backgroundWorker1.CancelAsync();
backgroundWorker1.Dispose();
AppendLog("Wykonywanie raportu przerwane" + "\n");
AppendLog("------------------------------------------" + "\n");
}
else
{
backgroundWorker1.CancelAsync();
backgroundWorker1.Dispose();
AppendLog("Wykonywanie raportu zakonczone" + "\n");
AppendLog("------------------------------------------" + "\n");
}
}