#vb.net #multithreading #user-interface
#vb.net #многопоточность #пользовательский интерфейс
Вопрос:
Я создал небольшое многопоточное приложение, используя VB.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 еще не запущена. возможно ли это?
Комментарии:
1. Что . Вы говорите о сетевом сервисе?
Ответ №1:
Я заметил несколько проблем.
- Вызов
Thread.Abort
inStopMonitoring
— вообще не очень хорошая идея. Вы должны использовать более безопасный механизм, который позволяет потоку корректно завершаться. - Я не вижу смысла вызывать
GC.Collect
вручную. В большинстве случаев это не требуется, и это может ухудшить производительность вашего приложения. - Рекурсивный вызов
MonitorNow
в конечном итоге приведет кStackOverflowException
. StartMonitor
вызывается изForm
конструктора. Это означает, что существует вероятность того, что рабочий процесс запускается до создания цикла сообщений. Эта проблема усугубляется тем фактом, чтоUSBLock
обработчики событий пытаются коснуться элементов пользовательского интерфейса, для которых сначала требуется создать этот цикл сообщений.USBLock
Дескрипторы событий поступают из рабочего потока, а затем пытаются коснуться элементов пользовательского интерфейса. Это абсолютно недопустимо. Это приведет к непредсказуемому и эффектному сбою приложения.
Несмотря на все это, трудно сказать, почему приложение зависает при запуске. Я бы сосредоточился на устранении вышеуказанных проблем, а затем опубликовал другой вопрос.