2014-10-25 2 views
0

Я работаю над приложением и обнаружил, что при удаленном подключении через TeamViewer и Radmin приложение зависает.
Когда он зависает, исключений нет, ui не отвечает и этот процесс НЕ вешается в мониторе ресурсов или в проводнике процессов.vb.net application freezes with TeamViewer

Некоторые основные спецификации для приложения: Подключается к 2 COM-портам. Один для ввода, один для вывода. Выходной сигнал COM также должен поддерживать живой сигнал каждые 5 секунд. Существует 4 потока рабочего рабочего, выполняющих различные задачи, начиная с обновлений пользовательского интерфейса и заканчивая речевым выходом, а также обрабатывая ввод данных. Пользовательский интерфейс отображает данные в реальном времени из трех отдельных источников данных. Два COM-порта, один из которых - MS SQL.

RDP не повесил приложение вообще.

Любые идеи о том, что может быть причиной этого?

Он работает на .NET 4.5.1, построенном в VS Ultimate 2013 с базой данных SQL 2012.

Я попытался изменить между 64-битным и 32-битным без каких-либо успехов.

EDIT Ответы на fsintegral.

  1. Все петли в приложении заканчиваются, но вызываются очень часто. Каждый таймер имеет повторение 1,5 - 5 секунд, и есть моменты, когда процесс в таймере занимает больше времени тика. Таймеры все обращаются к фоновому работнику и проверяют на .isBusy перед запуском процесса, чтобы избежать совпадения.

Таймеры предназначены для бесконечного запуска, но это отличается от бесконечного цикла.

  1. Есть ли способ проверить наличие невидимых диалоговых окон? Я не верю, что есть, но я хотел бы знать, как это сделать.

  2. Я потратил немало времени на оптимизацию времени загрузки данных для рабочего стола и получил каждый процесс до менее чем секунды для загрузки данных. Есть две вещи, которые заставляют один из процессов работать дольше. Один из них говорит предупреждение с помощью SpeachSynth и может занимать до 60 секунд на блок кода. Другой - это электронная почта, которую я ввел в процесс асинхронной работы, чтобы он не зависал приложение, если есть тайм-аут. Но приложение зависает, даже если эти два элемента не обрабатываются.

  3. Каскадные события. Это будут события, вызванные другими событиями? ЕСЛИ так, приложение не использует этот тип действия. Однако приложение ссылается на примерно 15 отдельных модулей, по крайней мере, из одного из фоновых работников. Я не верю, что это слишком высоко, но дайте мне знать, если это так. Я могу опубликовать некоторый псевдокод, если это проблема.

  4. Application.Sleep() не используется, но Application.DoEvents() находится в ожидании определенного количества времени.
    IE

    Dim 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.

Спасибо заранее.

+0

Некоторые подсказки при приложении замораживания: 1) Бесконечная петля. 2) Невидимое диалоговое окно. 3) Очень долгая загрузка данных. 4) каскадные события запускаются один за другим в цикле. 5) Application.Sleep() - Итак, отложите отладчик и используйте режим линии по строкам, чтобы найти проблему. Может быть где угодно; без какого-либо подозрительного кода для начала, но просто очень смутное описание ничего не может сделать. –

+1

Я больше не отвечаю на этот вопрос, никто никогда не говорит «спасибо», когда я объясню, что им нужно делать. Просто прочитайте http://blogs.msdn.com/b/dsui_team/archive/2012/10/31/debugging-windows-forms-application-hangs-during-systemevents.userpreferencechanged.aspx –

+0

Сегодня я буду управлять windbg, чтобы увидеть что он придумал. Спасибо, Ханс! –

ответ

0

Ok. Я понял.

В основном причина в том, как эти приложения удаленного просмотра влияют на пользовательский интерфейс приложения .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 захватывает пользовательский интерфейс таким образом, что postback никогда не отправлялся обратно в пользовательский интерфейс. С BeginInvoke postback игнорируется и, следовательно, больше не зависает с TeamViewer.

Благодарим вас за информацию о windbg. Но я не смог заставить его работать за статью, которую вы отправили. Я в конечном итоге использовал ProcessExplorer и создал файл дампа, чтобы узнать, в какой строке был виден код. Я пробовал использовать VS 2013 в режиме отладки, но приложение никогда не зависало при работе в отладке. Идите фигуру.

Благодарим вас за участие. Надеюсь, это поможет кому-то еще в будущем. Я потратил больше времени, чем я готов признать в этом вопросе, и я рад, что с этим поступил.

Если у вас есть дополнительные комментарии, сообщите мне.

I found this post to help with the issue

1

Hans Passant - Как иногда говорят в Америке "Чувак, ты Awsome!" Плохо, что люди не оценили то, что вы предоставили, но эта ссылка, хотя и сложная для среднего программиста VB.NET (я в этой категории), является спасателем жизни.
Мое решение оказалось немного отличным от того, что решило проблему OP. У меня была точно такая же проблема, описанная OP, однако переключение моих вызовов на begininvoke было не все, что мне нужно было сделать. Основываясь на вашей ссылке, стало ясно, что мне нужно убедиться, что я начал форму, которую я положил на другую тему, используя ApartmentSateSTA. Я не был явно устанавливая, что и надевал форму непосредственно на ThreadPool используя

System.Threading.ThreadPool.QueueUserWorkItem(AddressOf RunProgressForm)

Это, как представляется, просто использовать MTA нить из ThreadPool.Переход к созданию явного threading.thread, а затем с помощью

ProgBoxTHD = New Threading.Thread(AddressOf RunForm) 
ProgBoxTHD.IsBackground = True 
ProgBoxTHD.SetApartmentState(Threading.ApartmentState.STA) 
ProgBoxTHD.Priority = Threading.ThreadPriority.Normal 
ProgBoxTHD.Start() 

Это позволило дальнейшее перекачивание окна сообщений после TeamViewer изменяет настройки рабочего стола (который, когда мой applicaiton бы запереть). Также оказалось необходимым установить значение .IsBackground в True, иначе форма зависала бы на выходе, ожидая чего-то. Я знаю, что я должен это расследовать, но установка IsBackgrounds позволила потоку выйти, не дожидаясь остановки всего остального - и в тот момент, когда я выхожу, мне действительно все равно.

FYI - люди в TeamViewer были абсолютно никакой помощи. После того, как я удалил/переустановил, отключив DirectX, они не смогли оказать никакой дополнительной помощи. К сожалению, я использую несколько решений для совместного использования экрана, и только TeamViewer блокировал мою программу. Хотя решение действительно было исправить MY Программа, которую я действительно думаю TeamViewer должен посмотреть, как они меняют настройки рабочего стола при их подключении. Я потратил почти две недели на эту одну ошибку! Я использую TeamViewer для поддержки моих клиентов, и возникла проблема, когда TeamViewer подключен или отключен. Всякий раз, когда я оказывал поддержку, я возвращался к клиенту с помощью запертой программы! Это просто заставило меня выглядеть плохо!