Il nome della domanda è: "Aggiornamento della GUI dall'operatore in background", ma il nome corretto è: "Aggiornamento della GUI dall'operatore in background OPPURE segnalazione di più variabili (diversa da un numero intero) dal lavoratore in background "Aggiornamento della GUI dall'operatore in background
Per favore lasciatemi spiegare la mia situazione. In un programma ho un assistente in background che analizza le informazioni. Come risultato di questa analisi, gli elementi della GUI del modulo devono essere compilati con i dati necessari. In GUI vorrei aggiornare
- 2 DataGridViews
- 1 casella di riepilogo
- 5 etichette
A quanto ho capito - Posso solo nativamente rapporto 1 int
valore via ReportProgress()
metodo lavoratore in background.
Quindi la domanda è - come posso passare un List<>
(+ alcune altre variabili: string
, int
) tramite ReportProgress()
? Fondamentalmente - voglio aggiornare la GUI con le informazioni ma "1 intero" non lo farò. Quindi o dovrebbe essere possibile passare più variabili tramite un ReportProgress()
OPPURE posso usare un Invoke
all'interno dello stesso BackgroundWorker per aggiornare il GUI .. Personalmente non mi piace l'approccio Invoke
... Qual è la tua opinione?
Ecco il mio codice (vedi i commenti):
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() + ".");
}
Cosa non ti piace di 'Invoke'? –
ReportProgress ha anche un oggetto [UserState] (http://msdn.microsoft.com/en-us/library/a3zbdb1t (v = vs.110) .aspx) che è possibile trasmettere. – LarsTech
@Savanna non è che lo odio .. Sto cercando un'alternativa/migliore punto di vista per la mia soluzione attuale;) Forse spostando da BW a una "nuova discussione" sarà una soluzione .. Personalmente non lo faccio come invocando perché devo fare il controllo "if InvokeRequired, then ..." ma ancora una volta - se non ci sono alternative allora dovrò attenermi a questo – Alex