С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
C# .NET
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.79/28: Рейтинг темы: голосов - 28, средняя оценка - 4.79
Alex6911
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 81
1

Как узнать, что поток не завершен

25.02.2012, 16:38. Просмотров 5244. Ответов 8
Метки нет (Все метки)

Помогите с таким вопросом:

Есть класс, в котором создается поток подачи звукового сигнала определенное количество раз (countTick)
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  class SoundSignal
        {
            string fileWay; // путь к звуковому файлу
            public Thread Thrd;
 
           public SoundSignal(string way, int countTick)
            {
                fileWay = way;
                Thrd = new Thread(this.Sound);
                Thrd.Start(countTick);
            }
 
           private void Sound(object countTick)
            {
                for (int i = 1; i <= (int)countTick; i++) // countTick - количество воспроизведений сигнала
                {
                    System.Media.SoundPlayer sp = new System.Media.SoundPlayer(fileWay);
                    sp.Play();
                    Thread.Sleep(4000);
                }
           }
        }
Тут все работает.

Есть еще кнопка, у которой два состояния
1. Если нажали первый раз, то запустить поток
C#
1
SoundSignal sndSignal = new SoundSignal("notify.wav", 10);
2. Если я захочу досрочно остановить звуковой сигнал, то при повторном нажатии этой же кнопки остановить
поток. Вот тут у меня сложности. Написав sndSignal.Thrd.Abort() вылетает ошибка что sndSignal не существует

Подскажите, кто знает.

Добавлено через 6 минут
Пытался сделать так
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
        private void button1_Click_1(object sender, EventArgs e)
        {
 
            if ((string)Tag != "start")
            {
                Tag = "start";
                SoundSignal sndSignal = new SoundSignal("notify.wav", 10);        
            }
            else 
            {
                Tag = "stop";
                sndSignal.Thrd.Abort();
            }
        }
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.02.2012, 16:38
Ответы с готовыми решениями:

Как узнать, завершился ли поток?
Добрый день. Выполняю в потоке вот такой код (всего из одной строчки): ...

Как узнать закончил ли поток работу?
Для создания потоков использую ThreadPool.QueueUserWorkItem Как узнать...

Как уведомить первый поток о том, что второй закончил свою работу
Добрый день. Проблема такая. Есть 2 класса. Первый MyLogic - отвечает за...

Текущий поток должен быть задан как поток однопоточного контейнера (STA), чтобы вызовы OLE стали возможны
пишет:Текущий поток должен быть задан как поток однопоточного контейнера (STA),...

Как узнать что приложение запущено?
Как программно узнать что приложение (по пути к exe-файлу) запущено? И если оно...

8
kolorotur
Эксперт .NET
10732 / 8887 / 2226
Регистрация: 17.09.2011
Сообщений: 15,282
Завершенные тесты: 1
25.02.2012, 16:43 2
Сделайте sndSignal переменной класса и проверяйте, создана ли она.

Цитата Сообщение от Alex6911 Посмотреть сообщение
C#
1
sndSignal.Thrd.Abort();
Компьютер вы так же выключаете: выдернув шнур из розетки?
Используйте уведомления или флаги и завершайте поток должным образом.
1
Alex6911
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 81
25.02.2012, 16:56  [ТС] 3
Цитата Сообщение от kolorotur Посмотреть сообщение
Используйте уведомления или флаги и завершайте поток должным образом.
Поясните подробнее пожалуйста. Учу С# сам . Иногда не знаю чего, иногда туплю
0
kolorotur
Эксперт .NET
10732 / 8887 / 2226
Регистрация: 17.09.2011
Сообщений: 15,282
Завершенные тесты: 1
25.02.2012, 18:03 4
Цитата Сообщение от Alex6911 Посмотреть сообщение
Поясните подробнее пожалуйста
Да все просто до примитивного: вместо того, чтобы "убивать" поток, надо просто-напросто сообщать ему о завершении работы и уже в коде метода "красиво" его схлапывать:

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
private bool done; // Переменная-флаг, используется для оповещения потока о завершении.
public SoundSignal(string way, int countTick)
            {
                fileWay = way;
                Thrd = new Thread(this.Sound);
                Thrd.Start(countTick);
            }
 
           private void Sound(object countTick)
            {
                for (int i = 1; i <= (int)countTick; i++) // countTick - количество воспроизведений сигнала
                {
                    if (done) return; // Завершение потока по сигналу
 
                    System.Media.SoundPlayer sp = new System.Media.SoundPlayer(fileWay);
                    sp.Play();
                    Thread.Sleep(4000);
                }
           }
 
           public void StopSound()
           {
                      done = true;
           }
Лучше, конечно, использовать классы, предназначенные специально для оповещения потоков об окончании работы (вроде того же CancellationToken или BackgroundWorker'a), но для простых задач подойдет и обычный флаг булевого типа.
2
Alex6911
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 81
25.02.2012, 18:24  [ТС] 5
kolorotur,
Спасибо. Сразу не догнал, что при выходе из точки входа (private void Sound(object countTick) завершается и сам поток.

Добавлено через 11 минут
kolorotur,

Блин. Уперся в туже проблему что писал выше.

Как заставить работать конструкцию типа этой
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        private void button1_Click_1(object sender, EventArgs e)
        {
 
            if ((string)Tag != "start")
            {
                Tag = "start";
                SoundSignal sndSignal = new SoundSignal("notify.wav", 10);        
            }
            else 
            {
                Tag = "stop";
                sndSignal.StopSound();
            }
        }
    }

Почему пишет ошибку на sndSignal.StopSound() я понимаю. Но что сделать, что бы работало и не создавать отдельной переменной вне этого программного блока?
0
kolorotur
Эксперт .NET
10732 / 8887 / 2226
Регистрация: 17.09.2011
Сообщений: 15,282
Завершенные тесты: 1
25.02.2012, 18:37 6
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SoundSignal sndSignal;
private void button1_Click_1(object sender, EventArgs e)
        {
 
            if ((string)Tag != "start")
            {
                Tag = "start";
                sndSignal = new SoundSignal("notify.wav", 10);        
            }
            else 
            {
                Tag = "stop";
                sndSignal.StopSound();
            }
        }
    }
1
Alex6911
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 81
25.02.2012, 18:52  [ТС] 7
kolorotur,
Хотел обойтись без дополнительных глобальных переменных. Что бы не обрастать ими по ходу разработки программы. Ну да ладно. Сделал так.

Такой вопрос. Поток останавливаю так, как вы рекомендовали. При остановке потока вылетает ошибка "ссылка на объект не указывает на экземпляр объекта". Указатель стоит на sndSignal.StopSound(); Что не так теперь?
0
Casper-SC
Эксперт .NET
3638 / 1843 / 360
Регистрация: 27.03.2010
Сообщений: 5,169
Записей в блоге: 1
25.02.2012, 19:03 8
Ну можешь проверять на null
C#
1
2
3
                Tag = "stop";
                if (sndSignal != null)
                    sndSignal.Stop();
1
Alex6911
0 / 0 / 0
Регистрация: 21.11.2010
Сообщений: 81
25.02.2012, 19:09  [ТС] 9
Casper-SC,
Делал так. Ошибки нет, но и поток не останавливается.

Делал проверку на то, что поток завершен
C#
1
2
                if (!sndSignal.Thrd.IsAlive)
                    sndSignal.StopSound();
Выскакивает таже ошибка.

Хотя тут понятно. Потока нет, и проверять нечего
0
25.02.2012, 19:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.02.2012, 19:09

Как узнать, что панель задач переместилась?
Пользователь переместил панель задач. У меня нестандартное окно развёрнуто на...

Как узнать что удаленный клиент отключился
Здравствуйте. При подключение клиента создается список клиентов ...

Как узнать что значение переменной изменилось
Подскажите пожалуйста у меня есть класс А и класс B, класс B содержит поле С. В...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru