VB.net应用程序工作正常,但不响应任何事件。

huangapple go评论69阅读模式
英文:

VB.net application working but not responding to any events

问题

我有一个古老而复杂的VB.Net Windows应用程序,运行在.Net Framework 4.8上。如果我不断地与它交互,它运行得很好。但是,如果我让它闲置2-3小时,它就不工作了。我查看了任务管理器,甚至尝试点击程序本身,但它没有显示“未响应”,看起来它是在响应,没有冻结,但什么都不起作用。顺便说一下,主屏幕上只有一些用户点击并选择语言的标志。当我点击这些标志时,什么都不会发生。
我几乎记录了应用程序中发生的每个操作。但是我发现在我让应用程序闲置后根本没有任何日志。这意味着什么都没发生,应用程序停止响应事件。
看起来它决定取消所有事件。

我在任务管理器中查看过了,它没有使用任何CPU(在0.5%到3%之间反弹),任务管理器显示它运行得很好,并且在应用程序前面没有显示“未响应”。我甚至尝试使用Visual Studio暂停应用程序,以查看程序是否卡在任何循环中,但VS什么也没有显示,它显示你的应用程序在“外部代码”中。在Visual Studio或其他任何地方的诊断中没有任何奇怪的地方。

英文:

I have an old complex VB.Net Windows application that runs on .Net Framework 4.8. It runs just fine if I keep interacting with it. But if I leave it idle for 2-3 hours, it stops working. I looked in task manager and even tried clicking on the program itself and it does not say "not responding" and looks like it is responding and it is not frozen but nothing is not working. By the way, the main screen is just a couple of flags that the user clicks and selects the language. When I click on the flags, nothing happens.
I have a log for almost every action that happens in the application. But I can not find any log at all after I left the application idle. This means nothing happened and the application just stopped responding to events.
Looks like it decided to detach all the events.

I looked in Task Manager and it is not using any CPU (it bounces between 0.5% to 3%), and Task Manager says it is working just fine and not showing "not responding" in front of the application. I even tried to pause the application using Visual Studio to see if the program is stuck in any loop or not, but VS shows nothing and it says your application is in "External Code". There is nothing odd in the diagnosis of Visual Studio or anywhere else.

答案1

得分: 0

对于可能遇到与我遇到的相同问题的人:

我的问题与this thread中描述的问题相同。我按照this answer的方式查找问题的原因。我不得不将他们的代码转换成VB:

#Region "处理主线程之外的创建!!!"
   Private WithEvents FreezeTimer As New Windows.Forms.Timer
   Private Sub StartFreezeHandling()
      FreezeTimer = New Windows.Forms.Timer With {
         .Interval = 60000
      }
      FreezeTimer.Start()
   End Sub
   Private Sub StopFreezeHandling()
      FreezeTimer.Stop()
   End Sub

   Private Sub CheckSystemEventsHandlersForFreeze() Handles FreezeTimer.Tick
      Dim handlers = GetType(SystemEvents).GetField("_handlers", BindingFlags.NonPublic Or BindingFlags.[Static]).GetValue(Nothing)
      Dim handlersValues = handlers.[GetType]().GetProperty("Values").GetValue(handlers)

      For Each invokeInfos In (TryCast(handlersValues, IEnumerable)).OfType(Of Object)().ToArray()

         For Each invokeInfo In (TryCast(invokeInfos, IEnumerable)).OfType(Of Object)().ToArray()
            Dim syncContext = invokeInfo.[GetType]().GetField("_syncContext", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(invokeInfo)
            If syncContext Is Nothing Then Throw New Exception("syncContext missing")
            If Not (TypeOf syncContext Is WindowsFormsSynchronizationContext) Then Continue For
            Dim threadRef = CType(syncContext.[GetType]().GetField("destinationThreadRef", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(syncContext), WeakReference)
            If Not threadRef.IsAlive Then Continue For
            Dim thread = CType(threadRef.Target, Thread)
            If thread.ManagedThreadId = 1 Then Continue For
            Dim dlg = CType(invokeInfo.[GetType]().GetField("_delegate", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(invokeInfo), [Delegate])
            logSvc.Logging(New List(Of String)() From {$"SystemEvents handler '{dlg.Method.DeclaringType}.{dlg.Method.Name}' with name" +
                           " '{DirectCast(dlg.Target, Control).Name}' could freeze app due to wrong thread: " &
                           $"{thread.ManagedThreadId},{thread.IsThreadPoolThread},{thread.IsAlive},{thread.Name}"})
         Next
      Next
   End Sub
#End Region

我的问题是在主线程之外尝试扫描身份证。所以我以这种方式更改了调用:

scnDoc = Me.Invoke(Function()
                      Return boDesko.ScanPassport(oBook, CurrentScan, CurrLanguage)
                   End Function)
英文:

For the people who may have the same problem that I had:

My problem was the same as the problem described in this thread. I followed this answer to find what is causing the problem. I had to convert their code into VB:

#Region "Handle out of main thread creation!!!"
Private WithEvents FreezeTimer As New Windows.Forms.Timer
Private Sub StartFreezeHandling()
FreezeTimer = New Windows.Forms.Timer With {
.Interval = 60000
}
FreezeTimer.Start()
End Sub
Private Sub StopFreezeHandling()
FreezeTimer.Stop()
End Sub
Private Sub CheckSystemEventsHandlersForFreeze() Handles FreezeTimer.Tick
Dim handlers = GetType(SystemEvents).GetField("_handlers", BindingFlags.NonPublic Or BindingFlags.[Static]).GetValue(Nothing)
Dim handlersValues = handlers.[GetType]().GetProperty("Values").GetValue(handlers)
For Each invokeInfos In (TryCast(handlersValues, IEnumerable)).OfType(Of Object)().ToArray()
For Each invokeInfo In (TryCast(invokeInfos, IEnumerable)).OfType(Of Object)().ToArray()
Dim syncContext = invokeInfo.[GetType]().GetField("_syncContext", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(invokeInfo)
If syncContext Is Nothing Then Throw New Exception("syncContext missing")
If Not (TypeOf syncContext Is WindowsFormsSynchronizationContext) Then Continue For
Dim threadRef = CType(syncContext.[GetType]().GetField("destinationThreadRef", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(syncContext), WeakReference)
If Not threadRef.IsAlive Then Continue For
Dim thread = CType(threadRef.Target, Thread)
If thread.ManagedThreadId = 1 Then Continue For
Dim dlg = CType(invokeInfo.[GetType]().GetField("_delegate", BindingFlags.NonPublic Or BindingFlags.Instance).GetValue(invokeInfo), [Delegate])
logSvc.Logging(New List(Of String)() From {$"SystemEvents handler '{dlg.Method.DeclaringType}.{dlg.Method.Name}' with name" +
" '{DirectCast(dlg.Target, Control).Name}' could freeze app due to wrong thread: " &
$"{thread.ManagedThreadId},{thread.IsThreadPoolThread},{thread.IsAlive},{thread.Name}"})
Next
Next
End Sub
#End Region

My problem was trying to scan the ID card outside the main thread. So I changed the call this way:

    scnDoc = Me.Invoke(Function()
Return boDesko.ScanPassport(oBook, CurrentScan, CurrLanguage)
End Function)

huangapple
  • 本文由 发表于 2023年6月13日 17:50:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76463668.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定