Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/133: Рейтинг темы: голосов - 133, средняя оценка - 4.75
63 / 62 / 11
Регистрация: 28.12.2011
Сообщений: 280
1

Завершение потоков, после закрытия формы

30.08.2012, 19:21. Показов 24165. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
После закрытия формы в процессах продолжает висеть процесс.
Я так понимаю вот этот поток не закрывается.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
        //принятие данных от сервера
        void Receiver()
        {
            Thread th = new Thread(delegate()
            {
                while (client_running)
                {
                    try
                    {
                        byte[] bytes = new byte[1024];
                        // Принимает данные от сервера
                        client.Receive(bytes);
                        if (bytes.Length != 0)
                        {
                            string data = Encoding.UTF8.GetString(bytes);
                            textBox1.Text += data;
                        }
                    }
                    catch { }
                }
            });
            th.Start();
            threads.Add(th);
        }
Честно искал как отследить закрытие приложения чтобы попытаться убить все потоки в списке, подскажите как завершить поток при закрытии формы на крестик.
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.08.2012, 19:21
Ответы с готовыми решениями:

Завершение потоков при закрытии формы
Я щелкаю на закрыть окно, а программа не выходит из Debug. Я понял, что я запускаю потоки, но не...

Обновление формы после закрытия
После закрытия Form2 нужно чтобы данные на Form1 обновились(datagridview1, textbox1 и textbox2)...

Появление новой формы после закрытия предыдущей
Добрый всем вечер. Столкнулся с проблемкой: мне нужно при закрывании программы, открывалась новая...

После закрытия формы, ее поток продолжает работать
После закрытия приложения через процесс или крестик, поток помещается в фоновые процессы и...

18
6280 / 3565 / 898
Регистрация: 28.10.2010
Сообщений: 5,926
30.08.2012, 20:03 2
Смотрите события FormClosed, FormClosing
0
19 / 19 / 2
Регистрация: 27.09.2011
Сообщений: 155
31.08.2012, 11:48 3
была у меня такая "шляпа". так и не разобрался в чём дело, просто повесил на закрытие формы
C#
1
System.Environment.Exit(1);
помогло

Добавлено через 1 минуту
кстати пустой catch не комильфо.
7
145 / 142 / 11
Регистрация: 11.09.2011
Сообщений: 411
31.08.2012, 12:56 4
если есть доступная во всех методах ссылка на тред:

C#
1
2
3
4
5
6
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (thrdStart != null)  //thrdStart - глобальная ссылка на тред
                if (thrdStart.IsAlive)
                    thrdStart.Abort();
        }
0
63 / 62 / 11
Регистрация: 28.12.2011
Сообщений: 280
01.09.2012, 00:34  [ТС] 5
всем спасибо, вроде бы ничего не делал но проблема сама пропала...
0
0 / 0 / 0
Регистрация: 30.03.2017
Сообщений: 3
01.02.2014, 21:49 6
INF1NUM, спасибо, действительно помогает
0
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
02.02.2014, 11:15 7
Good1101, при работе с Thread не забывайте выставлять свойство IsBackground в true и таких проблем не будет.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
02.02.2014, 16:02 8
Неужели только у меня возникает чувство дискомфорта от завершения работы программы методом "а гори оно всё синим пламенем"?
Это я про принудительное завершение приложения, аборт потока или предоставление потока рантайму на уничтожение по своему усмотрению.

Под рукой же имеется все что нужно для нормального завершения работы: при закрытии приложения выставляем флаг client_running на false, закрываем сокет client и вызываем Join на потоке th. Если сокет заблочен из-за чтения, то он бросает исключение при вызове Receive (исключение ловим и пишем в лог, что сокет закрыт), потом переходит на следующую итерацию, в которой не проходит условие client_running, после чего работа потока благополучно завершается.
Все счастливы, дзен достигнут.

И нет необходимости стрелять себе в голову, когда пора идти спать.
1
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
02.02.2014, 16:10 9
Цитата Сообщение от kolorotur Посмотреть сообщение
Неужели только у меня возникает чувство дискомфорта от завершения работы программы методом "а гори оно всё синим пламенем"?
Я не думаю что это принципиально, если нужно выйти из приложения. Мы же не беспокоимся если процесс закрыт через диспетчер задач. Я про IsBackground.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
02.02.2014, 16:16 10
Цитата Сообщение от Grishaco Посмотреть сообщение
Я не думаю что это принципиально, если нужно выйти из приложения.
В данном конкретном примере — не принципиально, да.
Однако, лучше "с детства" приучаться к опрятности

Цитата Сообщение от Grishaco Посмотреть сообщение
Мы же не беспокоимся если процесс закрыт через диспетчер задач.
Оно, конечно, понятно, что при выдергивании шнура из розетки никакой finally не поможет — на то оно и экстренное/непредвиденное завершение.
Но при штатном завершении работу все-таки нужно заканчивать нормально.
1
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
02.02.2014, 16:25 11
Цитата Сообщение от kolorotur Посмотреть сообщение
Оно, конечно, понятно, что при выдергивании шнура из розетки никакой finally не поможет — на то оно и экстренное/непредвиденное завершение.
Но при штатном завершении работу все-таки нужно заканчивать нормально.
Не соглашусь, если с проектом работает несколько разработчиков и потоков запускается и завершается очень много, то пусть ставят IsBackground = true, а потом корректно завершают свои потоки. Во всяком случае это не приведет к тому что разработчик не учел некоторые моменты и процесс повис в памяти.

Добавлено через 5 минут
При этом что такое штатное завершение? А если у меня куча сборок, которые используются в моем проекте и там используются потоки, мне что каждый раз передавать флаг завершения через всю иерархию классов?
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
02.02.2014, 17:15 12
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Grishaco Посмотреть сообщение
потоков запускается и завершается очень много
Количество потоков — не повод валить их все без разбора

Цитата Сообщение от Grishaco Посмотреть сообщение
пусть ставят IsBackground = true, а потом корректно завершают свои потоки. Во всяком случае это не приведет к тому что разработчик не учел некоторые моменты и процесс повис в памяти.
Установка IsBackground = true очень быстро приведет к ситуации "поставил и забыл", и чем больше команда и объем работы на отдельного ее члена, тем больше будет этих ситуаций.
А вот если процесс повис в памяти, то это очень хорошее напоминание, что в коде косяк, и это напоминание позволит обнаружить и пофиксить этот косяк еще на стадии тестирования, а не приводить потом к undefined behavior на клиентской системе.

Цитата Сообщение от Grishaco Посмотреть сообщение
что такое штатное завершение?
Это риторический вопрос?
Спрашиваю без издевки, просто чтобы зря не расписывать ответ на вопрос, на который ответа не ожидается.

Цитата Сообщение от Grishaco Посмотреть сообщение
А если у меня куча сборок, которые используются в моем проекте и там используются потоки, мне что каждый раз передавать флаг завершения через всю иерархию классов?
Каждый класс сам следит за своими ресурсами — это ж азбука.
Задача разработчика, использующего стороннюю сборку, дать сигнал ее компонентам о завершении работы, например используя паттерн Disposable.
Задача разработчка, предоставляющего стороннюю сборку, предоставить интерфейс для корректного завершения ее компонентов, если таковой интерфейс необходим.

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

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

Но чтобы не возникало необходимости в хаках, в том числе и кому-то из-за вас ("вы" в данном контексте — не конкретно Вы, а некий гипотетический разраб), я выше и написал про приучение себя к опрятности "с детства".
Погадил — будь добр, прибери за собой.
4
438 / 362 / 100
Регистрация: 29.06.2010
Сообщений: 981
Записей в блоге: 1
02.02.2014, 17:34 13
Цитата Сообщение от kolorotur Посмотреть сообщение
Установка IsBackground = true очень быстро приведет к ситуации "поставил и забыл", и чем больше команда и объем работы на отдельного ее члена, тем больше будет этих ситуаций.
И чем грозит ситуация поставил и забыл? Обычно пользователь прежде чем закрыть программу пытается отменить операцию, тем самым завершается поток. Просто подстраховались на случай не предвиденной ошибки, которая может помешать завершить поток.

Цитата Сообщение от kolorotur Посмотреть сообщение
А вот если процесс повис в памяти, то это очень хорошее напоминание, что в коде косяк, и это напоминание позволит обнаружить и пофиксить этот косяк еще на стадии тестирования, а не приводить потом к undefined behavior на клиентской системе.
Особенно прикольно, когда это воспроизводится на компе у пользователя за 4000 км и без удаленного доступа. Тестеры вроде все делают как пользователь, а поймать не могут.

Цитата Сообщение от kolorotur Посмотреть сообщение
Каждый класс сам следит за своими ресурсами — это ж азбука.
Задача разработчика, использующего стороннюю сборку, дать сигнал ее компонентам о завершении работы, например используя паттерн Disposable.
Т.е. вы хотите сказать, что если я использую поток в своем классе, то я обязан реализовывать IDisposable?
А если вызывается статический метод и там создается поток?

Я считаю, что если разработчик использует поток, то он должен либо предоставить пользователю отменить операции идущую в потоке, любо выставить флаг завершения потока вместе с процессом. А не то получится, я же реализовал IDisposable, что же ты не использовал using.
0
Си-решеточник
140 / 134 / 60
Регистрация: 07.02.2011
Сообщений: 669
02.02.2014, 18:54 14
Цитата Сообщение от kolorotur Посмотреть сообщение
Но при штатном завершении работу все-таки нужно заканчивать нормально.
И всё же лень - двигатель быдлокода и от этого никуда не денешься.
0
624 / 495 / 43
Регистрация: 05.07.2010
Сообщений: 1,589
02.02.2014, 22:01 15
kolorotur, к сожалению, у большинства разработчиков отсутствуют инклудья, дающие способность понять необходимость писать аккуратно. Наша профессия вырождается, как выродилась в автослесарей профессия специалистов по двигателям. Культура производства в сфере ПО уже не востребована, как минимум вопрошающими здесь. Всё чаще прихожу к такому мнению.
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
03.02.2014, 16:18 16
Цитата Сообщение от Grishaco Посмотреть сообщение
И чем грозит ситуация поставил и забыл?
Всяко бывает: от "ничем" до "запоротым файлом" чем по-хуже. Зависит от того, что происходит в потоке.

Цитата Сообщение от Grishaco Посмотреть сообщение
Обычно пользователь прежде чем закрыть программу пытается отменить операцию, тем самым завершается поток.
Так это если операция все-таки подразумевает ее отмену.
Я ведь и говорю именно о разнице в подходе "отменить перед выходом" и "да пошло оно всё...".

Цитата Сообщение от Grishaco Посмотреть сообщение
Просто подстраховались на случай не предвиденной ошибки, которая может помешать завершить поток.
Вы меня, возможно, не так поняли. Я не говорю, что IsBackground — абсолютное зло.
Я о том, что меня коробит, когда программист даже не пытается нормально отменить параллельную операцию перед выходом.

Цитата Сообщение от Grishaco Посмотреть сообщение
Т.е. вы хотите сказать, что если я использую поток в своем классе, то я обязан реализовывать IDisposable?
Почему обязан? У меня же там слово "например" стоит.
Можно использовать любой удобный механизм, но механизм присутствовать должен. Банально для управления лайфтаймом объекта. А то объект заспавнил поток, сам при этом сдох, потому что больше не нужен, а поток продолжает что-то делать.

Цитата Сообщение от Grishaco Посмотреть сообщение
А если вызывается статический метод и там создается поток?
То создается другой статический метод для завершения работы этого потока.

Цитата Сообщение от Grishaco Посмотреть сообщение
Я считаю, что если разработчик использует поток, то он должен либо предоставить пользователю отменить операции идущую в потоке, либо выставить флаг завершения потока вместе с процессом.
Да кто ж спорит.
Вот у автора в коде предоставлена прекрасная возможность при выходе красиво отменить операцию, идущую в потоке. Эту возможность я описал в первом своем сообщении.
Я ж ворчу о том, что этой возможностью никто не воспользовался, почему-то все предложения были из серии либо убей, либо забей — само, мол, отвалится.

Цитата Сообщение от Grishaco Посмотреть сообщение
А не то получится, я же реализовал IDisposable, что же ты не использовал using.
Ну дык поэтому и встраивают защиту от идиота и закрывают ресурсы в деструкторе, если Dispose не был вызван.
1
63 / 62 / 11
Регистрация: 28.12.2011
Сообщений: 280
12.02.2014, 22:11  [ТС] 17
Всем спасибо конечно, но прошло уже полтора года с того момента как меня интересовал данный вопрос)
0
Эксперт .NET
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
13.02.2014, 11:33 18
Good1101, это ж проблема из серии вечных, она никогда не стареет
0
158 / 187 / 48
Регистрация: 25.11.2013
Сообщений: 978
13.02.2014, 11:41 19
Good1101, неправильно написан код работы лисенера
0
13.02.2014, 11:41
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
13.02.2014, 11:41
Помогаю со студенческими работами здесь

Выполнение некоторого действия после закрытия формы
Здравствуйте, есть проблемка. Существует первая форма MainForm, из которой я модально вызываю...

Обновление label в первой формы после закрытия второй
Добрый день! У меня есть две формы PZ6 и inputForm Вторая вызывается из первой по нажатию кнопки....

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

Обновление таблицы dataGridView после закрытия дочерней формы
Доброго времени суток. Собственно говоря есть главная форма, на которой находится dataGridView...

Как сохранить состояние TreeView после открытия закрытия формы?
На форме расположено "TreeView". Node_1 -- Node_1_1 -- Node_1_2 Node_2 -- Node_2_1 --...

После закрытия дочерней формы если у нее был public контролл, то к нему правомерно обрашаться?
Здравствуйте! Всем доброе утро. Вопрос в названии темы. Я вот если создаю новую форму Form2 form2...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru