Windows Form Filettatura ed Eventi in ListBox subito gli aggiornamenti, ma progressbar esperienze enorme ritardo

StackOverflow https://stackoverflow.com/questions/12095

Domanda

Il nostro team è la creazione di un nuovo sistema di flusso di lavoro assunzione per sostituire una vecchia.Ho ricevuto l'incarico con la migrazione dei vecchi dati nel nuovo schema.Ho deciso di fare questo attraverso la creazione di un piccolo progetto Windows Form come schema sono radicalmente diversi e dritto TSQL, gli script non sono una soluzione adeguata.

Il principale sigillato classe 'ImportController' che fa il lavoro, dichiara quanto segue delegato evento:

public delegate void ImportProgressEventHandler(object sender, ImportProgressEventArgs e);
public static event ImportProgressEventHandler importProgressEvent;

La finestra principale inizia un metodo statico in classe utilizzando un nuovo thread:

Thread dataProcessingThread = new Thread(new ParameterizedThreadStart(ImportController.ImportData));
dataProcessingThread.Name = "Data Importer: Data Processing Thread";
dataProcessingThread.Start(settings);

il ImportProgressEvent args porta una stringa di messaggio, un max valore di tipo int che la barra di avanzamento e un progresso int il valore di.Windows form subcribes per l'evento:

ImportController.importProgressEvent += new ImportController.ImportProgressEventHandler(ImportController_importProgressEvent);

E risponde a caso in questo modo, attraverso un proprio delegato:

    private delegate void TaskCompletedUIDelegate(string completedTask, int currentProgress, int progressMax);

private void ImportController_importProgressEvent(object sender, ImportProgressEventArgs e)
            {
                this.Invoke(new TaskCompletedUIDelegate(this.DisplayCompletedTask), e.CompletedTask, e.CurrentProgress, e.ProgressMax);
            }

Infine, la barra di avanzamento e la casella di riepilogo vengono aggiornati:

private void DisplayCompletedTask(string completedTask, int currentProgress, int progressMax)
        {
            string[] items = completedTask.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string item in items)
            {
                this.lstTasks.Items.Add(item);
            }

            if (currentProgress >= 0 && progressMax > 0 && currentProgress <= progressMax)
            {
                this.ImportProgressBar.Maximum = progressMax;
                this.ImportProgressBar.Value = currentProgress;
            }
        }

La cosa è ListBox sembra aggiornamento molto rapidamente, ma la barra di avanzamento non si muove fino a quando il batch è quasi completo, comunque ???che cosa dà ?

È stato utile?

Soluzione 4

@Giovanni

Grazie per il link.

@Vi

Non c'è nessun guadagno da threadpooling come so che sarà sempre e solo spawn di un thread.L'uso di un thread è puramente un reattivo interfaccia SQL Server viene pestato con letture e scritture.Certamente non è un breve thread.

Per quanto riguarda martelloni hai ragione.Ma, a quanto pare il mio problema era tra lo schermo e la sedia, dopo tutto.Mi sembra di avere un insolito batch di dati che ha molti molti molti di più di chiave esterna record rispetto agli altri lotti e succede solo a essere selezionata dall'inizio del processo di significato il currentProgress non ottenere ++'d per un buon 10 secondi.

@Tutti

Grazie per tutti i tuoi suggerimenti, mi ha fatto pensare, che mi ha fatto guardare altrove nel codice, che ha portato al mio ahaa momento di umiltà in cui mi dimostrano ancora una volta l'errore di solito è umano :)

Altri suggerimenti

Forse si può provare il componente BackgroundWorker.Si rende filettatura più facile.Qui alcuni esempi:

Magari al di fuori del campo di applicazione ma, a volte è utile fare una Application.DoEvents(); per rendere la gui parti rispondere all'input dell'utente, ad esempio premendo il pulsante cancel-su una barra di stato della finestra di dialogo.

Non è per caso l'esecuzione di Windows Vista?Ho notato esattamente la stessa cosa in un certo lavoro relative applicazioni.In qualche modo, sembra che ci sia un ritardo quando la barra di avanzamento "anima".

Sei sicuro che il thread dell'interfaccia utente è in esecuzione liberamente durante tutto questo processo?cioènon è seduto bloccato-up su un Join o qualche altro aspettare?Questo è quello che sembra a me.

Il suggerimento di utilizzare BackgroundWorker è buona, sicuramente superiore al tentativo di sledge-hammer il vostro modo di problema con un carico di Aggiornamento/Update chiamate.

E BackgroundWorker utilizzare un pool di thread, che è un amichevole modo di comportarsi di creazione di una propria breve thread.

Non c'è nessun guadagno da threadpooling come So che sarà sempre e solo uno spawn thread.L'uso di un thread è puramente per avere un reattivo interfaccia SQL Server è stato pestato con legge e scrive.Certamente non è un corto vissuto thread.

OK, mi rendo conto che e contento che hai trovato il tuo problema, ma hai guardato il BackgroundWorker?Fa più o meno esattamente quello che stai facendo, ma in un formato standard moda (es.senza il vostro propri delegati) e senza la necessità di creare un nuovo thread - che sono entrambi (forse piccolo, ma forse ancora utile) vantaggi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top