Цикл навсегда в приложении Windows Forms - PullRequest
4 голосов
/ 31 декабря 2011

Я использую Visual C # sand Я использую форму Windows, а не консольное приложение. Поэтому я работаю не с Main (), а с файлом формы. Я также очень плохо знаком с C #, поэтому извините, если некоторые мои вопросы глупы.

Что мне в основном нужно сделать, так это когда моя программа запускается, мне нужно, чтобы она продолжала работать бесконечно. Куда бы я положил этот код, так как у меня нет Main ()? Я помещаю это в функцию, у которой есть InitializeComponent () в нем? Мне нужно, чтобы цикл запускался сразу после запуска программы. Тем не менее, у меня есть некоторые переменные, которые мне нужно объявить перед циклом. В общем, мне нужно объявить переменные и запустить бесконечный цикл. Переменные являются глобальными.

Во-вторых, мне нужно разорвать бесконечный цикл, когда пользователь нажимает кнопку. Как бы я это сделал? Я думал что-то вроде:

while (buttonIsPressed == false)
{
   //do whatever I need to do
}

Однако я понял, что функция кнопки никогда не будет вызываться, так как я застрял в этом цикле. Я не могу установить переменную из функции кнопки, если я никогда не достигну функции кнопки из-за нахождения в бесконечном цикле. Есть идеи? Я думал о потоках, но у меня нет абсолютно никакого опыта работы с потоками, поэтому я немного неохотно пробую.


Дополнительно, из комментариев:

Приложение чата. Когда программа запускается, мне нужно сохранить прослушивания. Однако, когда пользователь нажимает «подключить», он прекращает слушать и вместо этого инициирует соединение

Я создаю чат-клиент. Таким образом, в основном, когда моя программа запускается, я нужно, чтобы продолжать слушать. Однако, когда пользователь нажимает «подключить» его необходимо прекратить прослушивание и вместо этого инициировать соединение

Ответы [ 4 ]

10 голосов
/ 31 декабря 2011

Это естественный вопрос для кого-то, кто происходит (совершенно) из другого фона.

Программирование приложений Windows Forms зависит от событий. Когда запускается приложение Windows Forms, загружается форма (проверьте файл Program.cs) и от вас скрывается главный цикл, чтобы сконцентрироваться на важных вещах в вашей программе.

Вам не нужно помещать что-либо в основной цикл, чтобы ответить на событие (например, событие с нажатием кнопки). Вы просто обрабатываете событие нажатия кнопки, создавая обработчик события для события Click кнопки). Вы можете использовать конструктор или сделать это вручную в коде.

Когда вы создаете метод для обработки события (и, как таковой, метод называется обработчиком события), он вызывается автоматически, когда событие инициируется / запускается. Например, обработчик метода для события Click для кнопки в вашей форме будет вызван, когда пользователь нажмет кнопку.

Этот раздел MSDN содержит всю необходимую информацию: Создание обработчиков событий в Windows Forms . Если вам нужно больше разъяснений, пожалуйста, спросите! :)

ОБНОВЛЕНИЕ: Создайте обработчик событий, как описано выше, а также создайте цикл в обработчике событий Form_Loaded. Обязательно вызовите Application.DoEvents (); внутри цикла. Таким образом, обработчик события для нажатия кнопки может быть обработан (в обработчике добавьте код, чтобы изменить логическое значение, которое сделало бы условие цикла ложным для отмены цикла).

ОБНОВЛЕНИЕ 2: Чтобы сделать этот ответ более полным, я упоминаю, что вам также следует рассмотреть возможность запуска цикла в новом потоке, а не в пользовательском интерфейсе (и, следовательно, избегайте необходимости использовать DoEvents, у которого есть свои недостатки, как указали мои коллеги). В следующем примере показано, как создать поток и отменить его при нажатии кнопки:

    System.Threading.Thread t;
    private void Form1_Load(object sender, EventArgs e)
    {
        //create and start a new thread in the load event.
        //passing it a method to be run on the new thread.
        t = new System.Threading.Thread(DoThisAllTheTime);
        t.Start();
    }

    public void DoThisAllTheTime()
    {
        while (true)
        {
            //you need to use Invoke because the new thread can't access the UI elements directly
            MethodInvoker mi = delegate() { this.Text = DateTime.Now.ToString(); };
            this.Invoke(mi);
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {
        //stop the thread.
        t.Suspend();
    } 

Наконец, рассмотрите возможность использования BackgroundWorker , который включает в себя создание и управление потоками для вас.

1 голос
/ 31 декабря 2011

Если вам нужно, чтобы ваша форма реагировала на нажатие кнопки, цикл должен выполняться в потоке, отличном от основного потока, вам подойдет BackgroundWorker .

1 голос
/ 31 декабря 2011

Зачем вам это нужно, чтобы продолжать цикл навсегда?

Интересно отметить, что ваша программа все равно делает это; это называется цикл сообщений. Он постоянно получает сообщения, поскольку пользователь взаимодействует с ним (нажимает кнопки и т. Д.)

Что вы на самом деле пытаетесь сделать? Конечно, уже есть конструкция, которая будет делать то, что вы ищете, будь то Таймер , BackgroundWorker и т. Д.

Для прослушивания сокета TCP существует класс TcpListener . Вы можете запустить поток для прослушивателя TCP для запуска.

0 голосов
/ 31 декабря 2011

Похоже, вы пытаетесь создать чат-клиент (см. в этом примере для некоторого примера кода).Для длительных параллельных выполнений я рекомендую вам создать и запустить поток , тело которого является упомянутым вами циклом while.

Главное, что вы должны понять, это то, что будет два потока исполнения.Одним из них является поток пользовательского интерфейса, который отвечает за рисование формы и реагирование на такие события, как нажатие кнопок (примечание: это будет циклически реагировать на события, когда пользователь взаимодействует с пользовательским интерфейсом).Другой поток - это циклический фоновый поток, который вы создадите для прослушивания информации о сети.Приведенный выше пример клиента чата создает поток в ответ на нажатие определенной кнопки, но, поскольку вы хотите начать цикл как можно скорее, я рекомендую создать и запустить поток в ответ на событие Load (просто дважды щелкните форму в режиме конструктора в Visual Studio, чтобы создать соответствующий обработчик события загрузки).

Сложная часть - это когда вы хотите обновить элемент пользовательского интерфейса из фонового потока.Чтобы сделать это без исключений, вы должны маршалировать вызов метода в потоке пользовательского интерфейса.Это может быть выполнено с помощью метода invoke на любом элементе управления (снова см. Ссылочный пример кода).

Чтобы выйти из цикла, вы можете установить для флага buttonPressed значение false в нажатой кнопкеобработчик события.Этот обработчик событий будет запущен в потоке пользовательского интерфейса, но общий флаг позволит фоновому потоку выйти из цикла в следующий раз, когда он выполнит итерацию к условному выражению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...