2011-05-05 88 views
2

我使用VB.NET創建了一個小型多線程應用程序。用戶手動運行此應用程序時沒有問題。當我在啓動時添加此應用程序時存在問題。它在我重新啓動系統後掛起。該應用程序仍在運行它的線程,但我看不到它的GUI,因爲它的凍結。如果我在任務管理器中殺死它並重新啓動,則應用程序可以正常工作。在啓動時添加這個應用程序的原因可能是什麼?.Net應用程序在啓動時添加時掛起

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 Framework服務尚未啓動的應用程序被加載。可能嗎?

+0

你在說什麼.NET服務? – 2011-05-05 14:32:50

回答

1

我注意到了幾個問題。

  1. 打電話Thread.AbortStopMonitoring不是一個好主意。你應該使用一個更安全的機制,讓線程正常結束。
  2. 我看不出手動調用GC.Collect。大多數時候這是不必要的,它可能會讓你的應用程序性能變差。
  3. 遞歸調用MonitorNow最終將導致StackOverflowException
  4. StartMonitor從構造函數Form被調用。這意味着有可能在創建消息循環之前啓動worker。由於事件處理程序試圖觸摸要求首先創建此消息循環的UI元素,因此這個問題更加複雜。
  5. USBLock事件句柄從工作線程進入,然後嘗試觸摸UI元素。這是絕對不允許的。這樣做會導致應用程序出現不可預知的驚人情況。

儘管所有這些都很難說啓動時應用程序掛起的原因。我將重點解決上述問題,然後發佈其他問題。