.Net应用程序在启动时添加时会挂起

时间:2011-05-05 03:12:18

标签: vb.net multithreading user-interface

我使用VB.NET创建了一个小型多线程应用程序。用户手动运行此应用程序时没有问题。我在启动时添加此应用程序时存在问题。重新启动系统后它会挂起。应用程序仍在运行其线程,但我无法看到它的GUI,因为它已冻结。如果我在任务管理器上杀了它并重新启动,应用程序工作正常。在启动时添加此应用程序时,可能的原因是什么?

Imports System.Threading

Public Class USBLock

  Public Event Lock()

  Public Event Unlock()

  Dim monitorThread As Thread

  Public Sub StartMonitoring()
    monitorThread = New Thread(AddressOf MonitorNow)
    monitorThread.Start()
  End Sub

  Public Sub StopMonitoring()
    Try
      monitorThread.Abort()
    Catch ex As Exception

    End Try

    GC.Collect()
  End Sub

  Private Sub MonitorNow()
    'LOOP HERE

    If xValid Then
      ' Enable Block Keyboard
      ' Hides Taskbar
      ' Disables Task Manager
      RaiseEvent Unlock()
    Else
      ' Disable Block Keyboard
      ' Shows Taskbar
      ' Enables Task Manaer
      RaiseEvent Lock()
    End If

    Thread.Sleep(1000)
    GC.Collect()

    MonitorNow()
  End Sub

End Class

Imports System.Reflection    
Imports System.IO

Public Class frmMain

    Friend WithEvents xMonitor As New USBLock
    Dim xCommandLineArgs As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
    Dim xState As Boolean = False
    Dim xFrmLock As Boolean

    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      xFrmLock = False
      userEnd = False

      If Not (xCommandLineArgs.Contains("-s") Or xCommandLineArgs.Contains("-S")) Then
        MyBase.WindowState = FormWindowState.Normal
      End If
    End Sub

    Public Sub New()
      MyBase.New()
      InitializeComponent()
      nIcon.Visible = True
      xCommandLineArgs = My.Application.CommandLineArgs

      If xCommandLineArgs.Contains("-s") Or xCommandLineArgs.Contains("-S") Then
        nIcon.Icon = Drawing.Icon.FromHandle(CType(imgIcon.Images(1), Bitmap).GetHicon())
        MyBase.Visible = False
        MyBase.WindowState = FormWindowState.Minimized
        StartMonitor()
      Else
        nIcon.Icon = Drawing.Icon.FromHandle(CType(imgIcon.Images(3), Bitmap).GetHicon())
      End If

    End Sub

    Private Sub lockPC() Handles xMonitor.Lock

      If Not xFrmLock Then
        frmLock.Show()
        xFrmLock = True
        nIcon.ShowBalloonTip(500, "Key Not Found", "PC has been locked!", ToolTipIcon.Error)
      End If

    End Sub

    Private Sub UnlockPC() Handles xMonitor.Unlock

      If xFrmLock Then
        frmLock.Close()
        xFrmLock = False
        nIcon.ShowBalloonTip(500, "Key Found", "PC has been unlocked!", ToolTipIcon.Info)
      End If

    End Sub

    Private Sub StartMonitor()
      'some codes here
      xMonitor.StartMonitoring()
      Me.Refresh()
    End Sub

    Private Sub StopMonitor()
      ' some codes here
      xMonitor.StopMonitoring()
    End Sub

    Private Sub btnOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
      StartMonitor()
    End Sub

    Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
      StopMonitor()
    End Sub        
End Class

或只是对这个主题的想法:程序在启动时挂起的原因是因为在.net框架服务尚未启动时加载了应用程序。有可能吗?

1 个答案:

答案 0 :(得分:1)

我注意到了几个问题。

  1. Thread.Abort中拨打StopMonitoring根本不是一个好主意。您应该使用更安全的机制,允许线程优雅地结束。
  2. 我认为手动调用GC.Collect毫无意义。大多数情况下这是不必要的,它可能会使您的应用程序性能更差。
  3. MonitorNow的递归调用最终将导致StackOverflowException
  4. StartMonitor构造函数调用
  5. Form。这意味着工作人员有可能在创建消息循环之前启动。 USBLock事件处理程序试图触摸需要首先创建此消息循环的UI元素,这个问题更加复杂。
  6. USBLock事件句柄从工作线程进入,然后尝试触摸UI元素。绝对不允许这样做。这样做会导致应用程序无法预测和失败。
  7. 尽管如此,很难说启动时应用程序挂起的原因。我将专注于解决上述问题,然后发布其他问题。