C # делать, пока остановка начала цикла - PullRequest
2 голосов
/ 29 июня 2011

Я пытаюсь сделать кнопку остановки для этого цикла, но он работает неопределенно долго, ничего не происходит, когда я нажимаю кнопку 2

bool dowhile = false;
private void button1_Click(object sender, EventArgs e)
{
    do
    {
        for (int i = listbox1.Items.Count - 1; i >= 0; i--)
        {
            string textstring = listbox1.Items[i].ToString();
            richTextBox1.AppendText("" + textstring + ": Done\n");
            Thread.Sleep(1000);
        }
    } while (!dowhile);
}
private void button2_Click(object sender, EventArgs e)
{
    this.dowhile = true;
}

, где я могу пойти не так?

извините за опечатку "lvlchanger", код в порядке, ничего не пропущено

Я также ищу не очень длинное исправление для этого:))

Ответы [ 4 ]

5 голосов
/ 29 июня 2011

Система не может обработать что-либо из очереди сообщений (т. Е. Нажатий кнопок, перерисовок и т. Д.) До тех пор, пока ваш button1_Click не завершится, чего никогда не произойдет.Это точно , что вызывает все эти сообщения "{бла} не отвечает" - код, который не отвечает на очередь сообщений быстро.

По сути, не делайте этого.Исправление hacky было бы немного DoEvents(), но НЕТ!делай это правильно;по сути, вместо этого обрабатывайте событие из button2_Click.Возможно, вам следует запустить обновление по таймеру?

2 голосов
/ 29 июня 2011

Thread.Sleep почти всегда неверный подход;когда вы обнаружите, что хотите использовать что-то подобное или Application.DoEvents в своем коде, пришло время сделать длинный шаг назад и подумать о том, что вы действительно делаете и почему это не работает.Новый дизайн должен быть в вашем будущем.

Реальная проблема здесь в том, что вы выполняете работу над потоком пользовательского интерфейса, который блокирует взаимодействие пользователя с вашим приложением.Ваш щелчок на кнопке Button2 распознается и обрабатывается после того, как цикл уже завершил обработку, после чего он абсолютно ничего не делает.

Это происходит потому, что потоки могут выполнять только одну задачу за раз.И, на самом деле, Thread.Sleep(100) только усугубляет это, потому что заставляет нить вращаться, а ничего не делает в течение 100 миллисекунд.Это еще 100 миллисекунд, которые потребуются для завершения цикла без какого-либо усиления.

Правильное решение этой (обычной) проблемы состоит в том, чтобы выделить цикл в отдельном потоке, используя что-то вроде BackgroundWorker класс .Запись MSDN имеет очень хороший пример ее использования, включая ваш конкретный вариант использования: позволяет пользователю отменить длительную фоновую задачу.

0 голосов
/ 29 июня 2011
private void button1_Click(object sender, EventArgs e)
{
    bool dowhile = false;private void button1_Click(object sender, EventArgs e){
    do 
    {
        for (int i = listbox1.Items.Count - 1; i >= 0; i--)
        {
            string textstring =listbox1.Items[i].ToString();
            richTextBox1.AppendText("" + textstring + ":` `Done\n");
            Thread.Sleep(1000);
        }
    } while (!lvlchanger && dowhile == false);
}

private void button2_Click(object sender, EventArgs e)
{
    this.dowhile = true;
}
0 голосов
/ 29 июня 2011

Добавьте Application.DoEvents() в цикл, чтобы приложение могло обрабатывать события из других источников.

/ EDIT Это должно работать, но ...

«Это почти никогда не правильный ответ» - Коди Грей

...