Jak uśpić wątek na 2 sekundy?

0

Witam chciałbym wczytywać dane po linijce co 2 sekundy do listboxa.

 public void SaveDataToListbox()
        {
            StreamReader sr = new StreamReader(@"C:\\test\\programTv.txt");

            string line;

            while ((line = sr.ReadLine()) != null)
            {
                Thread.Sleep(2000);
                listBox1.Items.Add(line);

            }
        }

Podany powyżej kod zatrzymuje aplikację a w listboxie nie wyświetlają się żadne dane. Z góry dziękuję za pomoc.

1

No to tak:
Po pierwsze nie możesz usypiać głównego wątku, bo aplikacja Ci się zawiesi, więc aby wywołać ten Twój kod musisz utworzyć nowy wątek.
Po drugie jak już utworzysz nowy wątek i w nim będziesz korzystał z kontrolek to musisz ten kod przekierować do tego wątku głównego, są różne sposoby, ja użyłem obiektu SynchronizationContext, możesz sobie poczytać o powinowadztwie do wątku.
Po trzecie poczytaj sobie o zwalnianiu zasobów, interfejsie IDisposable i metodzie Dispose, bo nie sprzątasz po wykonaniu operacji na pliku.
No i jak używasz znaku "@" to nie musisz dodawać ukośnika przed ukośnikiem, małpa zapewnia to, że ten string zostanie w takiej postaci jak jest

Tutaj Twój kod przerobiony tak, żeby działał:

    private void button1_Click(object sender, EventArgs e)
        {
            SynchronizationContext sc = SynchronizationContext.Current;
            Task.Factory.StartNew(() =>
            {
                using (StreamReader sr = new StreamReader(@"C:\test\programTv.txt"))
                {
                    string line;

                    while ((line = sr.ReadLine()) != null)
                    {
                        string tmpStr = line;
                        Thread.Sleep(2000);
                        sc.Post((obj)=>listBox1.Items.Add(tmpStr),null);
                    }
                }                 
            });
        }
0

Nie używaj Send tylko Post. Metoda Post nie czeka na zakończenie wykonywanych operacji, a Send tak i blokuje wątek roboczy, czyli wstrzymuje działanie wątku do czasu dodania tego stringa do listBoxa (wykonania instrukcji z metody Post w głównym wątku). No i takie coś niesie za sobą ryzyko zakleszczenia.

A błąd wywala Ci dlatego, że usunąłeś linijkę

string tmpStr = line;

Nie bez powodu była w tej pętli. Po prostu musisz utworzyć kopię tej wartości.

2

Ale po co tak kombinować? Przecież to można dużo prościej zrobić:

private async void button1_Click(object sender, EventArgs e)
{
    string[] fileContent = File.ReadAllLines(@"C:\test\programTv.txt");

    foreach(string s in fileContent)
    {
        listBox1.Items.Add(s);
        await Task.Delay(2000);
    }
}

Zauważ, że metoda button1_Click została wyposażona w słowo async. Dzięki czemu można w tej metodzie używać wywołań asynchronicznych.
W pierwszej linijce otwieram plik i jego zawartość ląduje w tablicy stringów.

Następnie jest prosta pętla, w której dodajemy poszczególne elementy do ListBoxa.
Task.Delay powoduje wstrzymanie tej pętli na 2 sekundy. Można tego użyć w taki sposób dzięki async/await. Ich użycie oddelegowuje zadanie do osobnego wątku, dzięki czemu nie wstrzymujemy głównego wątku aplikacji.

Dobrze jest też na początku tej metody (Click) zdeaktywować guzik: button.Enabled = false, a na końcu z powrotem go aktywować. Dzięki temu nie klikniesz w niego podczas już zaczętej operacji.

0

No można, ja jedynie przerobiłem jego kod, żeby działał. Może ma taką potrzebę, żeby wczytywać linijka po linijce. Jeżeli miałby strasznie długi plik to ładowanie wszystkiego do pamięci może trochę zająć, a tak to będzie miał wyświetlane od razu.

0

To to samo można osiągnąć wywołując File.ReadLines w pętli foreach :)

0

Tego tam właśnie brakowało. A co do kodu napisanego przeze mnie no to ja staram się nie robić zbytnio zmian w tym co ktoś już napisał. Dlaczego? No bo jak mu przerobisz cały kod, a on jest świeżakiem to może być mu ciężko go zrozumieć. A tak dodajesz nowe instrukcje oczywiście z komentarzem do czego to służy. Dodatkowo jak możesz zauważyć nie sprzątał po użyciu pliku, więc chciałem mu pokazać co musi zrobić, żeby było poprawnie. Najpierw trzeba zapoznać się z podstawami, a potem można pracować nad poprawą i upiększaniem kodu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0