Compact Framework/Filettatura - MessageBox visualizzata al di sopra di altri controlli dopo l'opzione prescelta
-
08-06-2019 - |
Domanda
Sto lavorando su un app che afferra e installa un sacco di aggiornamenti via un un server esterno, e hanno bisogno di qualche aiuto con la filettatura.L'utente segue questo processo:
- Click il pulsante
- Metodo di verifica la presenza di aggiornamenti, conte è tornato.
- Se è maggiore di 0, quindi chiedere all'utente se si desidera installare utilizzando MessageBox.Show().
- Se sì, si attraversa un ciclo e chiamare BeginInvoke() il metodo run() di ogni aggiornamento per l'esecuzione in background.
- Il mio aggiornamento di classe ha alcuni eventi che vengono utilizzati per aggiornare una barra di avanzamento, etc.
La barra di avanzamento aggiornamenti sono belle, ma il MessageBox non è completamente cancellato dallo schermo perché l'aggiornamento loop inizia proprio dopo che l'utente fa clic su sì (vedi screenshot qui sotto).
- Cosa devo fare per rendere il messagebox scompaiono immediatamente prima dell'aggiornamento ciclo inizia?
- Dovrei usare i Thread invece di BeginInvoke()?
- Dovrei fare l'aggiornamento iniziale di controllo su un thread separato e chiama MessageBox.Show() da quel thread?
Codice
// Button clicked event handler code...
DialogResult dlgRes = MessageBox.Show(
string.Format("There are {0} updates available.\n\nInstall these now?",
um2.Updates.Count), "Updates Available",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question,
MessageBoxDefaultButton.Button2
);
if (dlgRes == DialogResult.Yes)
{
ProcessAllUpdates(um2);
}
// Processes a bunch of items in a loop
private void ProcessAllUpdates(UpdateManager2 um2)
{
for (int i = 0; i < um2.Updates.Count; i++)
{
Update2 update = um2.Updates[i];
ProcessSingleUpdate(update);
int percentComplete = Utilities.CalculatePercentCompleted(i, um2.Updates.Count);
UpdateOverallProgress(percentComplete);
}
}
// Process a single update with IAsyncResult
private void ProcessSingleUpdate(Update2 update)
{
update.Action.OnStart += Action_OnStart;
update.Action.OnProgress += Action_OnProgress;
update.Action.OnCompletion += Action_OnCompletion;
//synchronous
//update.Action.Run();
// async
IAsyncResult ar = this.BeginInvoke((MethodInvoker)delegate() { update.Action.Run(); });
}
Screenshot
Soluzione
L'interfaccia utente non è un aggiornamento perché tutto il lavoro che sta accadendo nel thread di interfaccia utente.La tua chiamata a:
this.BeginInvoke((MethodInvoker)delegate() {update.Action.Run(); })
sta dicendo richiamare l'aggiornamento.Azione.Run() del thread che ha creato "questo" (form), che è il thread di interfaccia utente.
Application.DoEvents()
sarà davvero dare il thread dell'interfaccia utente la possibilità di ridisegnare lo schermo, ma sarei tentato di creare un nuovo delegato, e chiamare BeginInvoke su questo.
Questo verrà eseguito l'aggiornamento.Azione.Funzione Run() su un thread separato stanziati dal pool di thread.Si può quindi mantenere il controllo IAsyncResult fino a quando l'aggiornamento è completo, l'interrogazione l'aggiornamento in oggetto per i suoi progressi dopo ogni controllo (perché non si può avere un altro thread aggiornare la barra di avanzamento/UI), poi la chiamata di Applicazione.DoEvents().
Si si suppone anche per chiamare EndInvoke() dopo altrimenti si può finire perdite di risorse
Vorrei anche essere tentati di mettere un pulsante annulla nella finestra di dialogo di avanzamento, e aggiungere un timeout, altrimenti se l'aggiornamento si blocca (o richiede troppo tempo), la vostra applicazione sarà bloccato per sempre.
Altri suggerimenti
Hai provato a mettere un
Application.DoEvents()
qui
if (dlgRes == DialogResult.Yes)
{
Application.DoEvents();
ProcessAllUpdates(um2);
}
@ Giovanni Sibly
L'unico documentato eccezione alla regola che io sappia è in Windows Form, dove si sono ufficialmente autorizzati al Controllo delle chiamate.BeginInvoke senza preoccuparsi di Controllo delle chiamate.EndInvoke.
Tuttavia, in tutti gli altri casi, quando si tratta con l'inizio/Fine Asincrono modello si deve presumere che avrà una perdita, come lei ha dichiarato.