|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Расскажу о проблеммке на примере: Клиент исполняет код: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15.
Смысл кода: Команда - набрать номер (cds.dwData = 7) Параметр - собственно телефонный номер (cds.lpData = адрес памяти откуда его читать) (cds.cbData -длина номера, включая \0) Сервер выполняет команду, грубо вот так: Код: vbnet 1. 2. 3. 4.
Проблемка: пока ElseIf cds.dwData = 7 Then не отработает , т.е. SetupCall не будет выполнена ВЫЗЫВАЮЩЕЕ приложение будет также висеть . SetupCall может выполняться при плохой связи с SIP узлом несколько секунд, а если не дай бог там ошибка в настройках и указанного SIP узла не существует, то ошибки можно ждать и пару десятков секунд. То что ВЫЗЫВАЕМОЕ приложение подвешено - с этим здесь приходится мириться. Но то что подвешено ВЫЗЫВАЮЩЕЕ - непорядок. Т.е. я нажал на кнопку на Toolbar в ВЫЗЫВАЮЩЕМ приложении - она у меня остается нажатой. Как бороться? 14517814 Дмитрий77Второй неприятный эффект в таком же духе. Например посылаю SendMessage (data) в вызываемое приложение. Если в процедура обработки в вызываемом приложении требует какого-то времени, то опять же в вызывающем приложении будет подвисание. Как лечить? PostMessage вместо SendMessage? Ну, если ответа не требуется? А вот не работает PostMessage. И google говорит что это так и есть, то бишь WM_COPYDATA и PostMessage несовместимы. От вызывающего приложения требуется тупо сообщить вызываемому номер телефона, на что уходит миллисекунда. Вызывающее приложение не интересует удалось ли инициировать вызов по этому номеру или нет и прочие подробности. ... |
|||
:
Нравится:
Не нравится:
|
|||
04.07.2013, 06:06 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Дмитрий77, а если попробовать SendNotifyMessage? или SendMessageTimeout? Честно говоря у меня точно такая же проблема, пока нормального решения не нашёл: SendNotifyMessage - работает в ассинхронном режиме только в случае, если вызываемое приложение запущено не вызывающим приложением SendMessageTimeout -не хватило терпения разобраться с параметрами ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2013, 11:07 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Запустить еще одну программу, которая сделает SendMessage и будет висеть вместо вызывающей. А в дотнете можно было бы элементарно заюзать поток. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2013, 11:38 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
donpaulsа если попробовать SendNotifyMessage? или SendMessageTimeout? Пробовал. Ни один из этих вариантов начиная с PostMessage не будет работать конкретно с WM_COPYDATA. AntonariyЗапустить еще одну программу, которая сделает SendMessage и будет висеть вместо вызывающей. Ага, на каждую кнопку по exe-шнику. Смешно. Не, ну можно конечно один и тот же с параметрами запускать. Короче, не настолько актуальная проблема. Я на нее пока забил. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2013, 16:57 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Дмитрий77AntonariyЗапустить еще одну программу, которая сделает SendMessage и будет висеть вместо вызывающей. Ага, на каждую кнопку по exe-шнику. Смешно. Не, ну можно конечно один и тот же с параметрами запускать.А вариантов не много. Либо отдельный процесс, либо отдельный поток. Если поток, то нужно переделывать в ActiveX exe, но это сложно и не факт, что заработает на восьмерке. На серверах 2008+ не работает. Если отдельный процесс, то это запуск программы, можно другой, а можно своей же, но с параметром отправить сообщение и тут же выйти. В этом случае не нужно дополнительных настроек, запускается уже полностью доверенное приложение. ... |
|||
:
Нравится:
Не нравится:
|
|||
11.07.2013, 18:01 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Я тут с другой проблемой столкнулся на эту же тему. VB6 шлет запрос #100 в сторону C++: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
и получает от C++ ответ через WndProc: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
C++ код делает следующее: Код: plaintext 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.
Когда я даю команду #100 из VB6, то 1) VB6 висит 5 сек (Sleep(5000); в C++ коде) 2) потом пишет следующее в Debug: Код: vbnet 1. 2.
И здесь непонятно 2 вещи: 1) Если VB6 спит (ждет результата от отосланной SendMessage -строчка True), то как VB6 вообще умудряется отработать свою WndProc По идее там вообще должна быть "мертвая петля": SendMessage посланный из VB6 не получит результат, т.к. не сумеет вернуть результат SendMessage посланной из C++ 2) Я хочу чтоб C++ сразу возвращал результат SendMessage (чтоб VB6 не висела 5 сек), а "ответ" приходил независимо. То что "висит" C++ мне наплевать - там многопоточная прога. Что я должен сделать? Создать поток в C++, вернуть ответ из C++ сразу (чтоб исх. SendMessage в VB6 не висела) А потом в потоке выполнить в C++ чего надо и отсылать "Answer:Hello C++ Console Application" из этого потока потом убить поток в C++, как отдал ответ ??? ... |
|||
:
Нравится:
Не нравится:
|
|||
25.09.2013, 17:53 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Дмитрий77Что я должен сделать? Создать поток в C++, вернуть ответ из C++ сразу (чтоб исх. SendMessage в VB6 не висела) А потом в потоке выполнить в C++ чего надо и отсылать "Answer:Hello C++ Console Application" из этого потока потом убить поток в C++, как отдал ответ ??? Не ну если это сделать, то VB6 не будет висеть 5 сек. Вроде сделал. Но я задолбался параметры в поток передавать: Код: plaintext 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.
P.S. На C-шном форуме хрен помогут , строко-указателе-копатели хреновы. VB6 да и .NET - это видимо чтобы оградить себя от больных людей, которые бредят тем как устроена память и указатели, вместо чтоб получать быстрый практический результат относительно простым путем. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.09.2013, 06:22 |
|
Как убрать "подвешивание" вызывающего приложения при передаче SendMessage(WM_COPYDATA)?
|
|||
---|---|---|---|
#18+
Столкнулся с этим же багом, но с более серьезными последствиями. Код C++ посылает SendMessage (WM_COPYDATA) с информацией о ходе своих процессов в приложение VB6. Причем подобные отправки происходят из разных мест C-шного кода, в т.ч. из dll и т.п. Код: plaintext 1. 2. 3. 4. 5. 6.
На стороне VB6 код был типа: Код: vbnet 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Причем Function1 например может конвертировать файл запустив через Shell с ожиданием результата отдельный exe, Function2 например может отправлять e-mail. Т.е. это требующие времени операции, и при такой архитектуре процесс C++ будет висеть (пока SendMessage не вернет результат). А процесс на это такую грубость не рассчитан, в моем случае при нагрузке C++ мог свалиться на 100% CPU Usage с невозможностью вообще что либо сделать с компьютером. Идея следующая и вроде получилось. Обработчик WndProc вместо тупого запуска Function1 из-под себя пишет Message в массив-буфер, запускает одноразовый Timer (1 мс!!!) и отфутболивает SendMessage(результат получен). А ф-ция таймера работает с очередью сообщений. При этом как в ф-ции таймера, так и в Function1 если она использует цикл ожидания чего-либо используется DoEvents() с целью как минимум не препятствовать приему новых сообщений в буфер-массив. С буфером-массивом используется та же идея как при создании внутренней очереди Tray Notifications. Т.е. если принятое сообщение единственное, то оно обрабатывается сразу по тику таймера. Если не единственное, то просто кладется в конец очереди. А обработка происходит из ранее запущенной ф-ции таймера, кот. обработав предыдущее сообщение преступает к обработке следующего при его наличии. Код: vbnet 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.
Можно конечно использовать MailSlot вместо SendMessage. Сообщение кладется в MailSlot без подтверждения его приема (т.е. пославший ничего не ждет и не тормозит). но есть одно различие. MailSlot надо долбить по таймеру (на стороне приемника), а SendMessage принимается как только так сразу. В приведенном коде таймер используется только по факту прихода сообщения и создает минимальную задержку в 1 миллисекунду. ... |
|||
:
Нравится:
Не нравится:
|
|||
16.01.2014, 22:29 |
|
|
start [/forum/topic.php?fid=60&msg=38328414&tid=2156567]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
45ms |
get topic data: |
12ms |
get forum data: |
4ms |
get page messages: |
43ms |
get tp. blocked users: |
1ms |
others: | 17ms |
total: | 156ms |
0 / 0 |