0

我一直在开发一个应用程序,发现当通过 TeamViewer 和 Radmin 远程连接时,应用程序会冻结。
当它冻结时,没有异常,用户界面没有响应并且进程不会挂在资源监视器或进程资源管理器中。

应用程序的一些基本规格: 连接到 2 个 COM 端口。一个输入,一个输出。输出 COM 还需要每 5 秒发出一次保持活动信号。有 4 个后台工作线程运行从 UI 更新到语音输出以及处理数据输入的各种任务。UI 实时显示来自 3 个独立数据源的数据。两个是 COM 端口,一个是 MS SQL。

RDP 根本不会挂起应用程序。

关于可能导致这种情况的任何想法?

它在带有 SQL 2012 后端的 VS Ultimate 2013 中内置的 .NET 4.5.1 上运行。

我也尝试在 64 位和 32 位之间进行更改,但也没有任何进展。

编辑 对 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。

提前谢谢你。

4

2 回答 2

1

Hans Passant - 正如我们有时在美国所说的“老兄,你真棒!” 太糟糕了人们没有欣赏你提供的东西,但是这个链接,虽然对于普通的 VB.NET 程序员来说很复杂(我属于那个类别),但它是一个救命稻草
我的解决方案结果与解决 OP 问题的解决方案略有不同。我遇到了 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()

这允许在TeamViewer更改桌面设置后继续发送 Windows 消息(这是我的应用程序锁定的时间)。事实证明也有必要设置.IsBackground为 True,否则表单会在退出时挂起等待某些东西。我知道我应该对此进行调查,但是设置IsBackgrounds允许线程退出而无需等待其他任何东西停止 - 而在我退出的时候我真的不在乎。

仅供参考- TeamViewer的人完全没有帮助。在让我卸载/重新安装后,关闭 DirectX - 他们无法提供任何进一步的帮助。可悲的是,我使用了几种屏幕共享解决方案,只有 TeamViewer 锁定了我的程序。虽然解决方案确实是修复的程序,但我认为TeamViewer应该看看他们在连接时如何更改桌面设置。我仅在这个错误上就花了将近两周的时间!我使用TeamViewer为我的客户提供支持,当TeamViewer连接断开连接。每当我提供支持时,我都会给客户留下一个锁定的程序!那只是让我看起来很糟糕!

于 2017-08-20T17:44:16.070 回答
0

好的。我想到了。

基本上,问题的原因是这些远程查看应用程序如何影响 .NET 应用程序的 UI。

在我的应用程序中,有两个文本框是从应用程序中的各个线程更新的。我正在使用以下代码来更新文本。.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 需要在发布之前回发到 UI 并且 TeamViewer 以这种方式抓取 UI,以至于回发从未被发送回 UI。使用 BeginInvoke 会忽略回发,因此不会再无限期地挂起 TeamViewer。

感谢您提供有关windbg 的信息。但是我无法按照您发送的文章运行它。我最终使用了 ProcessExplorer 并创建了一个转储文件来找出代码挂在哪一行。我尝试在调试模式下使用 VS 2013,但在调试模式下运行时应用程序永远不会挂起。去搞清楚。

感谢您的输入。我希望这对将来的其他人有所帮助。我在这个问题上花费的时间比我愿意承认的要多,并且很高兴能完成它。

如果您有任何其他意见,请告诉我。

我发现这篇文章可以帮助解决这个问题

于 2014-10-26T08:27:36.593 回答