Poczekaj sekundę w uruchomionym programie

110
dataGridView1.Rows[x1].Cells[y1].Style.BackColor = System.Drawing.Color.Red;
System.Threading.Thread.Sleep(1000);

Chcę odczekać sekundę przed wydrukowaniem komórek siatki za pomocą tego kodu, ale to nie działa. Co mogę zrobić?

Selçuklu Ebrar
źródło
1
Jaki kod ma zostać uruchomiony po 1 sekundzie oczekiwania?
Allensb
1
Skąd wiesz, że to nie działa? Spróbuj przespać 10000 i zobacz, czy to działa. 1000 jest bardzo krótkie, aby ocenić, czy działa.
Missy
Działa to dobrze: System.Threading.Thread.Sleep (1000);
Andrew,

Odpowiedzi:

183

Czy to wstrzymanie, ale nie widzisz swojego czerwonego koloru w komórce? Spróbuj tego:

dataGridView1.Rows[x1].Cells[y1].Style.BackColor = System.Drawing.Color.Red;
dataGridView1.Refresh();
System.Threading.Thread.Sleep(1000);
Matt Dawdy
źródło
28

Osobiście uważam, że Thread.Sleepto kiepska realizacja. Blokuje interfejs użytkownika itp. Osobiście lubię implementacje timera, ponieważ czeka, a następnie odpala.

Stosowanie: DelayFactory.DelayAction(500, new Action(() => { this.RunAction(); }));

//Note Forms.Timer and Timer() have similar implementations. 

public static void DelayAction(int millisecond, Action action)
{
    var timer = new DispatcherTimer();
    timer.Tick += delegate

    {
        action.Invoke();
        timer.Stop();
    };

    timer.Interval = TimeSpan.FromMilliseconds(millisecond);
    timer.Start();
}
Mark Rowe
źródło
16

Funkcja oczekiwania za pomocą timerów, bez blokad interfejsu użytkownika.

public void wait(int milliseconds)
{
    var timer1 = new System.Windows.Forms.Timer();
    if (milliseconds == 0 || milliseconds < 0) return;

    // Console.WriteLine("start wait timer");
    timer1.Interval = milliseconds;
    timer1.Enabled  = true;
    timer1.Start();

    timer1.Tick += (s, e) =>
    {
        timer1.Enabled = false;
        timer1.Stop();
        // Console.WriteLine("stop wait timer");
    };

    while (timer1.Enabled)
    {
        Application.DoEvents();
    }
}

Użycie: wystarczy umieścić to w kodzie, który musi czekać:

wait(1000); //wait one second
Powiedziany
źródło
Tylko sugestia. Jeśli pomnożymy min przez 60000, nazwa parametru będzie bardziej znacząca. timer1.Interval = min * 60000;
Golda
Tak, masz rację, powinny to być milisekundy zamiast min. Zaktualizuję nazwę. Dzięki
powiedział
3

Wydaje mi się, że wszystko, co było nie tak, to kolejność. Selçuklu chciał, aby aplikacja odczekała sekundę przed wypełnieniem siatki, więc polecenie Uśpij powinno było pojawić się przed poleceniem wypełnienia.

    System.Threading.Thread.Sleep(1000);
    dataGridView1.Rows[x1].Cells[y1].Style.BackColor = System.Drawing.Color.Red;
Colin D.
źródło
3

Wydaje się, że .Net Core nie ma rozszerzenia DispatcherTimer.

Jeśli nie przeszkadza nam użycie metody asynchronicznej, Task.Delayspełni nasze potrzeby. Może to być również przydatne, jeśli chcesz czekać w pętli for z powodów ograniczających szybkość.

public async Task DoTasks(List<Items> items)
{
    foreach (var item in items)
    {
        await Task.Delay(2 * 1000);
        DoWork(item);
    }
}

Możesz poczekać na zakończenie tej metody w następujący sposób:

public async void TaskCaller(List<Item> items)
{
    await DoTasks(items);
}
Rich Hildebrand
źródło
To po prostu doskonały sposób. Dzięki ! :)
Deniz
2

Zajęte czekanie nie będzie poważną wadą, jeśli będzie krótkie. W moim przypadku zaistniała potrzeba wizualnego przekazania użytkownikowi informacji zwrotnej poprzez flashowanie kontrolki (jest to kontrolka wykresu, którą można skopiować do schowka, który zmienia swoje tło na kilka milisekund). Działa dobrze w ten sposób:

using System.Threading;
...
Clipboard.SetImage(bm);   // some code
distribution_chart.BackColor = Color.Gray;
Application.DoEvents();   // ensure repaint, may be not needed
Thread.Sleep(50);
distribution_chart.BackColor = Color.OldLace;
....
ChrisW
źródło
1

użyj dataGridView1.Refresh();:)

Coder SAJDFJF
źródło
1

Najlepszym sposobem na czekanie bez zawieszania się głównego wątku jest użycie funkcji Task.Delay .

Twój kod będzie więc wyglądał tak

var t = Task.Run(async delegate
{              
    dataGridView1.Rows[x1].Cells[y1].Style.BackColor = System.Drawing.Color.Red;
    dataGridView1.Refresh();
    await Task.Delay(1000);             
});
amitklein
źródło
0

Wypróbuj tę funkcję

public void Wait(int time) 
{           
    Thread thread = new Thread(delegate()
    {   
        System.Threading.Thread.Sleep(time);
    });
    thread.Start();
    while (thread.IsAlive)
    Application.DoEvents();
}

Funkcja wywołania

Wait(1000); // Wait for 1000ms = 1s
Savaş SERTER
źródło
-4

Może spróbuj tego kodu:

void wait (double x) {
    DateTime t = DateTime.Now;
    DateTime tf = DateTime.Now.AddSeconds(x);

    while (t < tf) {
        t = DateTime.Now;
    }
}
Bartek Winsławski
źródło
5
To jest poprawne rozwiązanie. Należy jednak dodać opis korzyści i szkód, na przykład wspomnieć, że ponieważ jest to rozwiązanie wymagające dużo czasu, zajmie ono czas procesora.
1
Krótsze rozwiązanie to lepsze rozwiązanie
BASEER ULHASSAN