Как запустить бесконечный цикл без зависания программы?(C #) - PullRequest
3 голосов
/ 04 ноября 2011

Я использую потоки в программе ac #, но процесс, который запускает потоки, вызывает другую функцию , которая имеет бесконечный цикл, который блокирует программу, это если я выберу другую опцию Форма Windows (например: закрыть и т. Д.) Больше не будет отвечать.

Этот цикл в необходим и на данный момент не может быть изменен.

Есть ли способ, которым я мог бы запустить этот цикл как «фон» и по-прежнему использовать другие параметры в программе, это: цикл не блокирует процесс (я бы не хотел использовать темы внутри потоков!).

Main Program
     |
     -------Thread(Function)
                       |
                       --------In the function ANOTHER
                               function is called with 
                               an infinite loop inside 
                               (this loop is NOT part of the 
                                Thread function directly)     

РЕДАКТИРОВАТЬ : добавить пример кода:

//Here I call the threads
private void userTest_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < numberOfDevices; i++)
        {
            try
            {
            Thread t = new Thread(unused => device(i, sender, e));
            t.IsBackground = true;
            t.Start();
            }
            catch (ThreadStateException f)
            {
                MessageBox.Show("ERROR:" + f);  // Display text of exception
            }
         }
      }

Функция потока:

    //This infinite loop is useless, so it could be deleted. This is not
    // the loop I´m talking about
    public void device(object i, object s, object f)
    {
        while (true)
        {
            if (!killEm)
            {
                int j = (int)i;
                EventArgs g = (EventArgs)f;
                BSSDK.BS_SetDeviceID(m_ConnectedDeviceHandle[j],
                 m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);

                UserManagement userTest = new UserManagement();


                userTest.SetDevice(m_ConnectedDeviceHandle[j],
                    m_ConnectedDeviceID[j], m_ConnectedDeviceType[j]);
                userTest.ShowDialog();

            }
            else
            {
                userTest.Dispose();
                MessageBox.Show("Why don´t u kill it!!?");
                break;
            }
        }
    }

В функции userTest.ShowDialog () - это бесконечный цикл, о котором я говорю

РЕДАКТИРОВАТЬ Это часть функции, которая вызывается в userTest.ShowDialog ()

private void user_Click(object sender, EventArgs e) {

//THIS IS THE LOOP I´M TALKING!
while (true) {
    Keep listening for an user put his finger in the device
    ...
    Do things with that finger template
    ...   
}

}

Спасибо.

Ответы [ 5 ]

2 голосов
/ 04 ноября 2011

Хорошо; Вот хорошие новости: вам не нужны темы вообще. Здесь у вас есть обычный компонент Windows Forms в форме «форм». Эти формы должны быть активными, чтобы реагировать на события. Вам не нужно создавать темы, чтобы сделать это, однако.

Ключ - статический класс System.Windows.Forms.Application, который имеет функцию, специально предназначенную для того, что вам нужно.

System.Windows.Forms.Application.Run();

Этот метод позволяет вашим Form объектам работать, реагируя на события, не позволяя функции, которую он вызывал, продолжать. Он блокируется, позволяя насосу сообщений отвечать до тех пор, пока не будет вызван Application.Exit() или другие подобные методы.

Что вы хотите сделать в вашем случае, так это создать все ваши формы и вызвать по очереди Show() для каждой из них ( не ShowDialog()), а затем, наконец, позвонить Application.Run(). Это дает вам то, что вы хотите.

Чтобы завершить свою программу, вам нужно, чтобы где-нибудь в ответ на что-то произошло Application.Exit() в ответ на что-то. У вас есть два варианта, которые будут работать быстро для вас:

  • Создайте отдельную «контрольную форму», которая представляет собой простую форму, которая при закрытии вызывает Application.Exit(), возможно, после циклического перебора всех ваших форм userManagement и, прежде всего, их закрытия. Вы можете сделать это с событием в событии Form.OnClosing формы управления, например.
  • Добавьте событие к каждому из событий Form.OnClosing форм userManagement, которое проверяет, когда закрыто последнее (или, возможно, закрыто ли какое-либо из них?), И, как указано выше, вызывает Application.Exit() там.

После того, как вы вызовете Application.Exit(), все открытые формы должны быть снесены (сначала я рекомендую сделать это вручную ...), а затем ваш вызов в главном потоке на Application.Run() завершится, и ваша программа продолжит работу. .. мы предполагаем, до конца.

<ч /> РЕДАКТИРОВАТЬ: Старый ответ, для потомков ...

Вы создаете новую тему не в том месте.

Не создавать новую тему для второго окна. Вместо этого создайте новый поток для длительной задачи и обязательно установите его в качестве фонового потока, чтобы он не оставался в живых даже при закрытии окон.

В идеале, этот цикл должен быть изящно отменен, но вы, похоже, предлагаете не касаться этого кода ...

0 голосов
/ 04 ноября 2011

Это не имеет ничего общего с потоками - даже если вы вызовете эту "функцию бесконечного цикла" из основного потока, она все равно повесит вашу программу.

Так что, кто бы ни создал эту функцию, он / она долженреализовали некоторый механизм его остановки, иначе это было бы совершенно бесполезно.Если не считать насильственного уничтожения потока ( Thread.Abort ), я предлагаю исследовать этот механизм и использовать его в своей теме.

Кстати, какова цель этой функции?Какая-то обработка сообщений?

--- EDIT ---

ОК, так что ваш "бесконечный цикл" на самом деле Form.ShowDialog.Внутри он содержит насос сообщений, и способ программно остановить этот насос - установить Form.DialogResult.Обратите внимание, что вам необходимо перенаправить все вызовы пользовательского интерфейса в соответствующие потоки, как указано в этом сообщении .

. Также попробуйте запустить из Application.Run (Форма) вместо Form.ShowDialog.

0 голосов
/ 04 ноября 2011

Вы можете создать новый поток http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx

или

Возможно, использование таймера будет целесообразным http://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.71%29.aspx

0 голосов
/ 04 ноября 2011

Кроме того, если это хорошая идея или нет, вы пробовали BackgroundWorker?

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=VS.80).aspx

0 голосов
/ 04 ноября 2011

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

...