Nazwa pytania brzmi: "Aktualizacja GUI od pracownika w tle", ale poprawna nazwa tego świata brzmi: "Aktualizacja GUI z tła roboczego LUB raportowanie wielu zmiennych (innych niż liczba całkowita) od pracownika tła "Aktualizacja GUI z działającego w tle pracownika
Proszę pozwolić mi wyjaśnić moją sytuację. W programie mam pracownika działającego w tle, który analizuje informacje. W wyniku tej analizy - elementy GUI formularza powinny być wypełnione niezbędnymi danymi. W GUI chciałbym zaktualizować
- 2 datagridviews
- 1 listbox
- 5 etykiet
Jak rozumiem - mogę tylko natywnie raport 1 int
wartość poprzez ReportProgress()
metody pracownik w tle.
Więc pytanie - w jaki sposób mogę przekazać List<>
(+ kilka innych zmiennych: string
, int
) Via ReportProgress()
? Zasadniczo - chcę zaktualizować GUI z informacją, ale "1 liczba całkowita" po prostu nie zrobi. Tak więc powinno być możliwe przekazanie wielu zmiennych przez ReportProgress()
LUB mogę użyć Invoke
z wewnątrz samego BackgroundWorker, aby zaktualizować GUI .. Osobiście nie podoba mi się podejście Invoke
... Jaka jest Twoja opinia?
Oto mój kod (patrz komentarze):
private void button9_Click(object sender, EventArgs e) // start BW
{
bw.DoWork += new DoWorkEventHandler(backgroundWorker1_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker1_RunWorkerCompleted);
bw.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);
bw.WorkerReportsProgress = true;
bw.WorkerSupportsCancellation = true;
bw.RunWorkerAsync(10);
}
private void button10_Click(object sender, EventArgs e) // cancel BW
{
bw.CancelAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
int count = (int)e.Argument;
for (int i = 1; i <= count; i++)
{
if (bw.CancellationPending)
{
e.Cancel = true;
break;
}
List<List<string>> list_result = new List<List<string>>();
list_result = Proccess();
bw.ReportProgress(list_result.Count()); // right now I can only return a single INT
/////////// UPDATE GUI //////////////
// change datagridview 1 based on "list_result" values
// change datagridview 2
// change listbox
// change label 1
// change label ..
Thread.Sleep(20000);
}
MessageBox.Show("Complete!");
e.Result = sum;
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
prog_count++;
listBox1.Items.Add("Count: (" + prog_count.ToString() + "/20). Found: " + e.ProgressPercentage.ToString() + ".");
}
Co nie podoba ci się w "Wywołuj"? –
ReportProgress ma również obiekt [UserState] (http://msdn.microsoft.com/en-us/library/a3zbdb1t (v = vs.110) .aspx), który można przekazać. – LarsTech
@Savanna to nie to, że go nienawidzę .. Szukam alternatywnego/lepszego punktu widzenia do mojego obecnego rozwiązania;) Może przejście od BW do "nowej Nici" będzie rozwiązaniem .. Osobiście nie lubię wywoływać, ponieważ muszę zrobić sprawdzanie "jeśli InvokeRequired, to ...", ale znowu - jeśli nie ma alternatywy, będę musiał trzymać się tego jednego – Alex