Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Разработка Windows Forms > Invoke()


Автор: Random13 2.6.2008, 18:07
Всем привет.
Ситуация следующая - есть прибор, посылающий непрерывно пакеты после команды старт. У него есть своя память, где они, в случае не успевания обработки, скапливаются. После комнды стоп генерация пакетов прекращается. сред догребает все и завершает работу.
при приходе пакетов происхоит определенное рисование на форме. Сделано все вызовами Invoke() из срэда.
Проблема вот в чем. Хотелось бы дать, при закрытии, среду некоторое время для догребания пакетов(опустошения буфера девайса) и коррекного выхода, в случае проблем сделать аборт.
Проблема в том, что использовать Thread.Sleep() в главном среде не получается, так как Invoke(), вызывемый из среда обрабатывается, понятно в главном среде, а во время слипа он тормозится и сред девайса ждет окончание его выполнени то есть слип главновного среда торозит и сред девайса.
Нужен либо Invoke(), который бы не ожидался вызывающим средом, либо слип, не прерывающий обработку ассинхронных вызовов. Что-то найти ничего не могу. Никто ничего не подскажет ?
При дебогировании у среда девайса висит статус WaitSleepJoin.

Автор: Дрон 2.6.2008, 18:28
Цитата(Random13 @  2.6.2008,  18:07 Найти цитируемый пост)
Проблема в том, что использовать Thread.Sleep() в главном среде не получается, так как Invoke(), вызывемый из среда обрабатывается, понятно в главном среде, а во время слипа он тормозится и сред девайса ждет окончание его выполнени то есть слип главновного среда торозит и сред девайса.
Нужен либо Invoke(), который бы не ожидался вызывающим средом, либо слип, не прерывающий обработку ассинхронных вызовов. Что-то найти ничего не могу. Никто ничего не подскажет ?

А зачем вообще там нужен Thread.Sleep() ?

Я правильно понимаю задачу: при закрытии формы поток должен закрываться не сразу, а выработать весь буфер?
Так надо сделать просто сделать флаг (переменную типа bool), который будет сигнализировать потоку, что пора завершать работу. Если этот флаг установлен, то и к форме больше не обращаемся.

А чтобы процесс не завершался до тех пор, пока поток не отработал до конца, то у потока должно быть выставлено свойство IsBackground = false

PS: Или я что-то недопонимаю -- просто язык какой-то странный, чем-то похож на русский, но явно не он.
Цитата(Random13 @  2.6.2008,  18:07 Найти цитируемый пост)
... слип главновного среда ... 

Ух-ты.
Цитата
При дебогировании у среда девайса

Ух-ты ещё раз!  smile 

Автор: Random13 2.6.2008, 19:11
Ты не совсем правильно понял. Булевая константа в среде есть - так постоенны почти все среды, закрывающиеся по условию. Проблема с главного среда сказать среду закончится, подождать некоторе время (дать ему закончится), потом проверить его состояние, если все еще жив - убить. Причем за ради этого городить таймер на форме тоже не хотелось бы...
Задача не такая простая...
Проблема не сказать среду закончится, а проконтролировать из главного потока его корректное завершение.

Автор: Дрон 2.6.2008, 19:41
А если попробовать Thread.Join с таймаутом?

Добавлено через 13 минут и 24 секунды
При этом главный поток, конечно, всё равно уйдёт в ожидание, но в потоке устройства ты просто не делай больше Invoke, после того как пришла команда остановится, или вообще делай асинхронный вызов через BeginInvoke. Тогда рабочему потоку не нужно будет дожидаться пока главный проснётся.

Автор: Random13 3.6.2008, 09:53
хорошая функция, но не спасает. все равно поток девайся тоже виснет с главным потоком при ожидании этой функции.
уже и DynamicInvoke пробовал - он вообще не рисует нормально на форме.
я и так переcтаю вызывать его после команды остановки, видимо подвисает на текущей комаде. BeginInvoke тоже не спасает - работает так же.

Автор: amarenkov 3.6.2008, 11:58
Random13 , попробуй использовать WindowsFormsSynchronizationContext. У него есть методы Post и Send для синхронной и асинхронной отправки сообщений. Может тебе поможет.

Автор: Random13 3.6.2008, 14:33
с помощью WindowsFormsSynchronizationContext работает вроде бы, но перегружает систему. и при очередном обновлении формы в конце концев падает.
в общем надоело мне ве это - просто убиваю поток абортом и все.
еще проблему создает загрузка, наверное. При работе приходит около 90 пакетов в секунду.
Invoke(), BeginInvoke() работают без проблем - только вот блокируют, вызывающий их поток, при блокировке основного потока.

Автор: -Mikle- 3.6.2008, 20:07
Цитата(Random13 @  2.6.2008,  21:07 Найти цитируемый пост)
при приходе пакетов происхоит определенное рисование на форме

Цитата(Random13 @  3.6.2008,  17:33 Найти цитируемый пост)
При работе приходит около 90 пакетов в секунду

И ты 90 раз в секунду вызываешь Invoke (BeginInvoke) в котором делаешь отрисовку формы? Ты не привел код, но подозреваю что так. ИМХО не хорошо это, так часто рисовать. Лучше сделать буферизацию пакетов и рисовать сразу махом несколько изменений, например после 50 пакетов, а не по одному.

А по поводу твоего вопроса, посмотри это http://msdn.microsoft.com/ru-ru/library/w9f75h7a(en-us).aspx
Если не разберешься, пиши.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)