Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.10.2015, 16:31   #1
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию Сообщение из потока

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

Сам по себе будильник представляется объектом Alarm test, внутри которого содержится поле Thread alarm, то есть - поток.
Так же в классе Alarm описывается потоковая функция void ThreadProcess(), которая и должна выполняться потоком Thread alarm.

В этой самой функции выполняется расчёт даты и времени, когда должен сработать будильник; от рассчитанной даты вычитается текущая дата. Полученное значение представляется как время задержки потока - TimeSpan delay; после всего расчёта вызывается функция Thread.Sleep(delay). У такого метода есть один единственный изъян: если изменить системное время - будильник сработает неправильно, поэтому недельное тестирование затруднительно; но это уже не важно.

После всей этой задержки на форме должно отобразиться сообщение, которое должно быть результатом работы будильника.
Я могу в самом потоке вызвать MessageBox.Show(), но из-за этого работа потока будет приостановлена до закрытия окна сообщения, что является неприемлемым.
Лепить на форме таймер, или второй поток тоже не интересно, ведь не зря нужный поток вертится непосредственно в объекте будильника.

Первое, что пришло в мою голову - имея объект формы выбросить туда сообщение посредством некоего события. Собственно, как это сделать ?
Я могу в объект будильника закинуть ссылку на объект формы, но всё сводится к вызову MessageBox.Show(), что должно происходить в другом потоке, посредством некоторого события. Как описать это событие ? И как это событие вызывать ? У этого события должна быть функция, в которой и будет вызываться MessageBox.Show(), но это будет выполнено уже не в потоке объекта будильника, а в форме, в которой произошло событие.

P.S. Вопросы выделены жирным.
Подпись ? Не, не слышал ...

Последний раз редактировалось OmegaBerkut; 20.10.2015 в 16:40.
OmegaBerkut вне форума Ответить с цитированием
Старый 20.10.2015, 16:42   #2
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Цитата:
но из-за этого работа потока будет приостановлена до закрытия окна сообщения
.BeginInvoke или SynchronizationContext Post
Цитата:
Я могу в самом потоке вызвать MessageBox.Show()
Делать что-либо с UI напрямую не из UI потока не рекомендуется. Надо либо Invoke, либо SynchronizationContext использовать.

В C#5/.NET 4.5 есть более удобные варианты с async/await и IProgress
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.

Последний раз редактировалось Alex11223; 20.10.2015 в 16:45.
Alex11223 вне форума Ответить с цитированием
Старый 20.10.2015, 16:46   #3
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

Цитата:
Сообщение от Alex11223 Посмотреть сообщение
Делать что-либо с UI напрямую не из UI потока не рекомендуется. Надо либо Invoke, либо SynchronizationContext использовать.
Я знаю, это ещё одна причина, по которой я хочу вызывать событие формы из этого потока; а это событие, находясь в объекте формы, будет вызывать MessageBox.Show().
Проблема в том, что я не знаю, как это сделать.
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 20.10.2015, 16:52   #4
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Так же как и любое другое событие, только либо генерировать его из BeginInvoke, либо в его обработчике BeginInvoke.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Старый 20.10.2015, 16:55   #5
OmegaBerkut
Спокойный псих
Участник клуба
 
Аватар для OmegaBerkut
 
Регистрация: 19.03.2013
Сообщений: 1,538
По умолчанию

А я могу дёргать события других объектов из своего потока ? И в каком потоке будет выполняться код этих событий ?
Подпись ? Не, не слышал ...
OmegaBerkut вне форума Ответить с цитированием
Старый 20.10.2015, 17:02   #6
Alex11223
Старожил
 
Аватар для Alex11223
 
Регистрация: 12.01.2011
Сообщений: 19,500
По умолчанию

Что? Кого?
Где инициируете его, в том и выполнится. В сообщении выше ж все написано, либо сам объект должен инициировать событие в UI потоке (BeginInvoke или SynchronizationContext Post), либо подписчик в обработчике события.
Ушел с форума, https://www.programmersforum.rocks, alex.pantec@gmail.com, https://github.com/AlexP11223
ЛС отключены Аларом.
Alex11223 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как получить доступ к методу потока(TThread) из основного потока? Pcrepair Общие вопросы Delphi 3 30.03.2013 14:52
Завершение потока coNsept Общие вопросы C/C++ 3 20.06.2012 19:42
Должно быть 3 потока. А диспетчер задач показывает, что потока создано 2 BEL9ILLI Общие вопросы Delphi 3 06.12.2011 20:26
при закрытии потока(Tthread) посылать на форму код ответа или сообщение Человек_Борща Общие вопросы Delphi 2 14.12.2010 21:19
Как узнать номер потока из самого потока? GaMeSTeR Помощь студентам 0 03.12.2010 09:50