Приложение vb.net зависает с TeamViewer
Я работал над приложением и обнаружил, что при удаленном подключении через TeamViewer и Radmin приложение зависает.
Когда он зависает, исключений нет, пользовательский интерфейс не отвечает, и процесс НЕ зависает в мониторе ресурсов или в проводнике процессов.
Некоторые основные характеристики для приложения: Подключение к 2 COM-портам. Один для ввода, один для вывода. Для выхода COM также требуется сигнал поддержания активности каждые 5 секунд. Существует 4 фоновых рабочих потока, выполняющих различные задачи от обновлений пользовательского интерфейса до речевого вывода, а также обработки ввода данных. Пользовательский интерфейс отображает данные в режиме реального времени из 3 отдельных источников данных. Два COM-порта, один MS SQL.
RDP вообще не вешает приложение.
Любые идеи о том, что может быть причиной этого?
Он работает на.NET 4.5.1, встроенной в VS Ultimate 2013 с SQL 2012 Backend.
Я пробовал переключаться между 64-битным и 32-битным без какого-либо прогресса.
РЕДАКТИРОВАТЬ Ответы на fsintegral.
- Все циклы в приложении заканчиваются, но вызываются очень часто. Каждый таймер имеет 1,5 - 5-секундное повторение, и бывают случаи, когда процесс в таймере занимает больше времени, чем тик. Все таймеры обращаются к фоновому работнику и проверяют наличие.isBusy перед началом процесса, чтобы избежать дублирования.
Таймеры предназначены для работы бесконечно, но это отличается от бесконечного цикла.
Есть ли способ проверить наличие невидимых диалоговых окон? Я не верю, что что-либо существует, но я хотел бы знать, как убедиться.
Я потратил много времени на оптимизацию времени загрузки данных на одного фонового работника и сократил нагрузку на каждый процесс менее чем на секунду. Есть две вещи, которые заставляют один из процессов работать дольше. Одним из них является оповещение с помощью SpeachSynth, которое может занять до 60 секунд на блок кода. Другой - электронная почта, которую я включил в асинхронный процесс, чтобы предотвратить зависание приложения в случае тайм-аута. Но приложение зависает, даже если эти два элемента не обрабатываются.
Каскадные события. Будут ли это события, вызванные другими событиями? Если это так, приложение не использует этот тип действия. Однако приложение вызывает около 15 отдельных модулей по крайней мере от одного из фоновых рабочих. Я не верю, что это слишком много, но дайте мне знать, если это так. Я могу опубликовать псевдокод, если это вызывает беспокойство.
Application.Sleep () не используется, но Application.DoEvents() находится в ожидании определенного промежутка времени.
IEDim startTime As Date = Now Dim timePassed As TimeSpan = Now - startTime Do Until timePassed.TotalSeconds > 5 timePassed = Now - startTime Application.DoEvents() Loop
Основная причина неопределенности заключается в том, что я надеялся, что эта проблема была известна в TeamViewer или Radmin в зависимости от типов элементов в приложении. IE SQL версия, COM-порты и BW.
Спасибо заранее
2 ответа
Хорошо. Я понял.
По сути, причина проблемы заключается в том, как эти приложения удаленного просмотра влияют на пользовательский интерфейс приложения.NET.
В моем приложении есть два текстовых поля, которые обновляются из различных потоков в приложении. Я использовал следующий код для обновления текста. Метод.Invoke был проблемой.
Delegate Sub SetTextCallback(ByVal [text] As String, ByRef txtHomeActiveDataStream As TextBox, ByVal type As String)
Public Sub ReceivedText(ByVal [text] As String, ByRef txtHomeActiveDataStream As TextBox, ByVal type As String) 'input from ReadExisting
Dim receivedString As String = text
Dim currentText As String
If txtHomeActiveDataStream.InvokeRequired Then
Dim x As New SetTextCallback(AddressOf ReceivedText)
txtHomeActiveDataStream.Invoke(x, New Object() {(text), txtHomeActiveDataStream, type})
Else
txtHomeActiveDataStream.Text &= receivedString
End If
End Sub
Изменив метод с.Invoke на.BeginInvoke, я смог предотвратить зависание приложения. По-видимому, это связано с тем, что.Invoke требует обратной передачи в пользовательский интерфейс перед выпуском, а TeamViewer захватывает пользовательский интерфейс таким образом, что обратная передача никогда не отправляется обратно в пользовательский интерфейс. При использовании BeginInvoke обратная передача игнорируется и, следовательно, больше не зависает бесконечно с TeamViewer.
Спасибо за информацию о Windbg. Но я не смог заставить его работать по статье, которую вы отправили. В итоге я использовал ProcessExplorer и создал файл дампа, чтобы узнать, на какой строке висит код. Я пытался использовать VS 2013 в режиме отладки, но приложение никогда не зависало при работе в режиме отладки. Пойди разберись.
Спасибо за ваш вклад, ребята. Я надеюсь, что это поможет кому-то еще в будущем. Я потратил больше времени, чем готов признать по этому вопросу, и рад, что с ним покончено.
Если у вас есть дополнительные комментарии, пожалуйста, дайте мне знать.
Ханс Пассант - Как мы иногда говорим в Америке, "Чувак, ты потрясающий!" Жаль, что люди не оценили то, что вы предоставили, но эта ссылка, хотя и сложная для среднего программиста VB.NET (я в этой категории), спасает жизнь.
Мое решение оказалось немного отличным от решения проблемы ОП. У меня была та же самая проблема, описанная OP, однако переключение моих вызовов на begininvoke было не единственным, что мне нужно было сделать. По вашей ссылке стало ясно, что мне нужно убедиться, что я запустил форму, которую я поместил в другой поток, с помощью ApartmentSateSTA. Я не устанавливал это явно и помещал форму непосредственно в пул потоков, используя
System.Threading.ThreadPool.QueueUserWorkItem(AddressOf RunProgressForm)
Это, кажется, просто использует поток MTA из пула потоков. Переключение на создание явного threading.thread
а затем с помощью
ProgBoxTHD = New Threading.Thread(AddressOf RunForm)
ProgBoxTHD.IsBackground = True
ProgBoxTHD.SetApartmentState(Threading.ApartmentState.STA)
ProgBoxTHD.Priority = Threading.ThreadPriority.Normal
ProgBoxTHD.Start()
Это позволило продолжить прокачку сообщений Windows после того, как TeamViewer изменил настройки рабочего стола (когда мое приложение заблокировалось). Также оказалось необходимым установить .IsBackground
Истина, иначе форма будет зависать на выходе в ожидании чего-либо. Я знаю, что должен изучить это, но установка IsBackgrounds позволила потоку завершиться, не дожидаясь остановки чего-либо еще - и в тот момент, когда я выхожу, мне действительно все равно.
К вашему сведению, ребята из TeamViewer абсолютно не помогли. После того, как я удалил / переустановил, отключил DirectX - они не смогли оказать дальнейшую помощь. К сожалению, я использую несколько решений для совместного использования экрана, и только TeamViewer заблокировал мою программу. Хотя решение действительно заключалось в том, чтобы исправить МОЮ программу, я считаю, что TeamViewer должен взглянуть на то, как они меняют настройки рабочего стола при подключении. Я потратил почти две недели на одну эту ошибку! Я использую TeamViewer для поддержки своих клиентов, и проблема возникла при подключении или отключении TeamViewer. Всякий раз, когда я оказывал поддержку, я заканчивал тем, что оставлял клиента с заблокированной программой! Это только заставило меня выглядеть плохо!