C #: внутренняя работа: события, Control.BeginInvoke и выход из программы = прерывание? - PullRequest
1 голос
/ 15 марта 2012

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

Поскольку я использую сокеты Asynch, некоторые из этих сообщений возвращаются в разных потоках, поэтомукак только они попадают в основной поток, я проверяю InvokeRequired и, если true, я использую this.BeginInvoke для обработки журналирования.

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

Я знаю, что иногда может случиться так, что несколько сообщений переключаются, но сейчас я могу с этим смириться.По какой-то причине, если я использую Invoke вместо BeginInvoke, сервер зависнет, если я остановлю его, пока клиенты подключены, и даже не выдаст никаких исключений.Но используя BeginInvoke, я преодолел это.

Мой вопрос касается понимания того, как работают события и BeginInvoke в случае завершения программы.Если событие находится в очереди или BeginInvoke был вызван непосредственно перед закрытием программы, будет ли оно немедленно завершено, отменяя все?или он выполнит все ожидающие действия, в моем случае зарегистрирует ожидающее сообщение, а затем выйдет?

Ответы [ 2 ]

2 голосов
/ 16 марта 2012

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

    private bool closing;

    protected override void OnFormClosing(FormClosingEventArgs e) {
        if (!closing) {
            closing = true;
            // Do your stuff
            //...
            this.BeginInvoke(new Action(() => this.Close()));
            e.Cancel = true;
        }
        base.OnFormClosing(e);
    }
0 голосов
/ 16 марта 2012

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

Когда только что был вызван BeginInvoke, и программа была немедленно остановлена.Остальные операции (регистрация) не будут выполнены, потому что поток из пула потоков

...