Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
81 / 75 / 29
Регистрация: 08.08.2013
Сообщений: 431
Записей в блоге: 1
1

Как правильно завершить поток (программа часы в Label)

14.11.2016, 17:50. Показов 1286. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Здравствуйте, есть простая многопоточная программа - на форме в Label отображается время (программа во вложении).
Программа работает, но есть проблема с завершением программы.
Если просто нажать на крестик, то программа вылетает с ошибкой.
А если сначала нажать на кнопку "Остановить поток" и потом на крестик, тогда все правильно завершается.
Вопрос: почему программа некорректно завершается, когда я нажимаю на крестик, ведь код на событие кнопки и на крестике (Form1_FormClosing) один и тот же.

Кликните здесь для просмотра всего текста
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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
namespace MyExp
{
    public partial class Form1 : Form
    {
        Thread thread1;
        private MyTime worker;
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            label1.Text = DateTime.Now.ToString("HH:mm:ss");
 
            worker = new MyTime();
            worker.TimeChanged += IzmTime;
            worker.WorkCompleted += StopTime;
 
            thread1 = new Thread(worker.metod1);
            thread1.Start();
        }
 
 
        private void IzmTime()
        {
 
            Action action = () =>
            {
                label1.Text = DateTime.Now.ToString("HH:mm:ss");
            };
            Invoke(action);
        }
 
 
        private void StopTime()
        {
            worker.Cancel();
        }
 
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)  //++
        {
             StopTime();
        }
 
        private void btn_StopTime_Click(object sender, EventArgs e)
        {
             StopTime();
        }
 
    }
 
    class MyTime
    {
        public event Action TimeChanged;  //событие
        public event Action WorkCompleted;  //событие
 
        public bool _canceled = false;
 
        public void Cancel()
        {
            _canceled = true;
        }
 
 
        public void metod1()
        {
            while (true)
            {
                if (_canceled)
                {
                    MessageBox.Show("Поток остановлен");
                    break;
                }
                Thread.Sleep(1000);
                TimeChanged();
            }
            WorkCompleted(); // конец
 
        }
    }
}
Вложения
Тип файла: 7z MyExp.7z (30.8 Кб, 4 просмотров)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.11.2016, 17:50
Ответы с готовыми решениями:

Как правильно завершить поток
Всем привет. Что я делаю не так ? Поток запускается и работает хорошо, но вот при завершении...

Как правильно завершить поток сервера?
{ Listener = new TcpListener(Settings.ip, Settings.port); // Создаем "слушателя" для...

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

Как правильно завершить поток без исключения ThreadInterruptedException?
В общем, есть отдельный проект dll-ки с компонентом, наследующим MonthCalendar. В нем дополнительно...

5
81 / 75 / 29
Регистрация: 08.08.2013
Сообщений: 431
Записей в блоге: 1
14.11.2016, 17:58  [ТС] 2
можно конечно использовать thread1.Abort(); но хочется понять, почему вылетает ошибка в первом варианте
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
14.11.2016, 18:15 3
добавить в FormLoad:
C#
1
thread1.IsBackground = true;
тогда вторичный поток будет завершен если завершён основной

Добавлено через 6 минут
п.с. до запуска потока
0
81 / 75 / 29
Регистрация: 08.08.2013
Сообщений: 431
Записей в блоге: 1
14.11.2016, 18:19  [ТС] 4
Да, с таким свойством работает.
Но почему не работает мой вариант?
При нажатии на крестик вызывается событие Form1_FormClosing, в нем вызывается метод StopTime(); который вызывает метод worker.Cancel(); который делает переменную _canceled = true; которая прерывает цикл, после чего поток сам должен завершиться.
0
64 / 65 / 44
Регистрация: 05.12.2014
Сообщений: 475
14.11.2016, 18:32 5
Потому что поток не завершается сразу при вызове Cancel, CLR сама решает когда его закончить, поэтому возникает момент когда лебела уже нет а поток всё пытается его поменять. (инфа не 100% )
0
7 / 7 / 3
Регистрация: 10.04.2015
Сообщений: 57
14.11.2016, 20:59 6
Попробуй в событии Form1_FormClosing Отписываться от евентов связанных с формой которая закрывается.
0
14.11.2016, 20:59
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.11.2016, 20:59
Помогаю со студенческими работами здесь

Как правильно завершить поток QThread и выйти из него?
Здравствуйте, форумчане! Есть GUI-приложение, кнопка в окне приложения запускает цикл обмена...

Как правильно завершить поток, который лочит мьютекс в цикле?
Есть поток, созданный посредствам CreateThread, который в цикле лочит именной мьютекс, ну типа...

Правильно завершить поток
Здравствуйте!!! Делаю программу через поток. Вот код #include <vcl.h> #pragma hdrstop ...

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


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

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