2009-07-28 10 views
9

Pracuję w C# i WPF, bardzo nowe dla obu.Jak wyświetlić postępy w zajętości pętli?

Mam pętlę, która odczytuje wiele danych z zewnętrznego źródła. Proces ten trwa około 20 sekund i chcę pokazać postęp użytkownika. Nie potrzebuję żadnych ozdobnych pasków postępu, więc zdecydowałem się przedstawić postępy w etykiecie, która powie "Krok 1/1000", a następnie zmienić na "Krok 2/1000" itd.

Mój kod wygląda jak to:

// "count" is the number of steps in the loop, 
// I receive it in previous code 

String countLabel = "/"+count.ToString(); 

for (i = 0; i < count; i++) 
{ 
    ... do analysis ... 
    labelProgress.Content = "Step "+i.ToString()+countLabel 
} 

jednak podczas tej analizy ekran jest „zablokowany” i postęp nie pokazują jak postęp. Rozumiem to zachowanie z mojej przeszłości w C++, gdzie prawdopodobnie miałbym oddzielny wątek pokazujący pasek postępu otrzymujący powiadomienia z pętli lub jakąś formę odświeżenia/odświeżenia lub zmuszając okno/aplikację do przetworzenia swojej kolejki wiadomości.

Jaki jest właściwy sposób, aby to zrobić w języku C#? Nie jestem związany z wytwórnią, więc jeśli istnieje prosty ekran postępu bar popup można używać zamiast tej etykiety byłoby również świetne ...

Dzięki

+0

Może to być pomoc dla Ciebie , ** 100% testowane ** http://stackoverflow.com/a/42995210/6863414 –

Odpowiedz

11

Przenieś do pracy i BackgroundWorker użyj metody ReportProgress.

for (i = 0; i < count; i++) 
{ 
    ... do analysis ... 
    worker.ReportProgress((100 * i)/count); 
} 

private void MyWorker_ProgressChanged(object sender, 
    ProgressChangedEventArgs e) 
{ 
    taskProgressBar.Value = Math.Min(e.ProgressPercentage, 100); 
} 
+0

Czy to wątek bezpieczne? –

+1

Tak, powinno być. Twój pracownik działający w tle jest tylko w jednym wątku, aktualizacja paska postępu jest tylko w wątku interfejsu użytkownika. Każdy wątek inny niż wątek interfejsu użytkownika będzie generował wyjątek, jeśli spróbuje zaktualizować wartość. Dzięki tej metodzie masz zagwarantowane bezpieczeństwo gwintów. – user7116

2

Interfejs użytkownika nie jest aktualizowany ze względu na fakt, że bieżący wątek ma wyższy priorytet niż wątek interfejsu użytkownika, który ostatecznie ustawi etykietę;). Dopóki twój wątek nie skończy się na twoich rzeczach, na końcu zaktualizuje twoją etykietę.

Na szczęście dla nas, nie jest własnością Dyspozytor na każdym kontroli WPF, który pozwala odpalić nowy wątek z innym priorytetem ..

labelProgress.Dispatcher.Invoke(DispatcherPriority.Background, 
        () => labelProgress.Content = string.Format("Step {0}{1}", i, countLabel)); 

Ten ogień się nitki w tle i dostanie pracę Gotowe! Można również spróbować innych DispatcherPriority opcje

PS Wziąłem również wolność, aby dodać metodę anonimową i naprawić swój ciąg parsowania nieco .. nadzieję, że nie przeszkadza ..

3
//Create a Delegate to update your status button 
    delegate void StringParameterDelegate(string value); 
    String countLabel = "/" + count.ToString(); 
    //When your button is clicked to process the loops, start a thread for process the loops 
    public void StartProcessingButtonClick(object sender, EventArgs e) 
    { 
     Thread queryRunningThread = new Thread(new ThreadStart(ProcessLoop)); 
     queryRunningThread.Name = "ProcessLoop"; 
     queryRunningThread.IsBackground = true; 
     queryRunningThread.Start(); 
    } 

    private void ProcessLoop() 
    { 
     for (i = 0; i < count; i++) 
     { 
      ... do analysis ... 
      UpdateProgressLabel("Step "+i.ToString()+countLabel); 
     } 
    } 

    void UpdateProgressLabel(string value) 
    { 
     if (InvokeRequired) 
     { 
      // We're not in the UI thread, so we need to call BeginInvoke 
      BeginInvoke(new StringParameterDelegate(UpdateProgressLabel), new object[] { value }); 
      return; 
     } 
     // Must be on the UI thread if we've got this far 
     labelProgress.Content = value; 
    } 
+0

BackgroundWorker jest dostarczany, więc nie musisz obsługiwać całego bałaganu odradzania się z wątku. – user7116

+0

@sletterlettervariables Wartość tej metody polega na tym, że pozwala ona na większą elastyczność niż tylko przekazywanie liczby całkowitej z powrotem do osoby dzwoniącej - możesz zrobić WSZYSTKO (np. Przekazać komunikat o statusie, na przykład) – ean5533

Powiązane problemy