在VB.net中干净地停止线程以避免双重错误处理



我在干净地停止线程时遇到了这个问题。我试图将其简化为下面代码的更基本的版本,我想知道我的方法在这里是否完全错误。

我有一个带有一堆UI元素的Form1,这些元素需要在BackgroundCode运行时更新(我在这里运行它,所以它是一个单独的线程,不会占用UI(,然后我通过调用子来更新UI

(Me.Invoke(Sub()
something.property=something 
End Sub))

我还试图处理一些由外部文件传递给应用程序的错误。我使用了一个计时器来检查文件,如果它存在,我会获取内容并将其传递给我的ErrorHandler。这将错误写入日志文件,在屏幕上显示,然后中止后台工作程序,使程序无法继续运行。我遇到的麻烦是通过执行BackgroundThread。Abort((操作本身正在触发ErrorHandler。有没有办法要求BackgroundThread干净地停止?如果代码中出现其他错误,我希望BackgroundThread触发ErrorHandler。

我想知道是否使用像"ErrorIsRunning"这样的全局布尔值来限制ErrorHandler子项,使其只能运行一次,但这开始让人觉得越来越棘手,我想知道我是否已经完全偏离了轨道,是否有更好的方法来处理整件事。

Public Class Form1

Dim BackgroundThread As New Thread(AddressOf BackgroundCode)
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

‘Hide Error Page
ErrorPage.Visible = False
ErrorLabel.Visible = False
‘Start Background Code
BackgroundThread.Start()        

End Sub
Private Sub BackgroundCode()
Try

‘<Background code which runs over a number of minutes>

Catch.ex as Exception
ErrorHandler(“Error with BackgroundCode: “ + ex.Message)
End Try

End Sub

Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick

Dim ErrorFile As String =  “C:MyErrorFile.Err”
Dim ErrorContents As String

If File.Exists(ErrorFile) Then
Timer.Enabled = False
ErrorContents = File.ReadAllText(ErrorFile).Trim()
ErrorHandler(ErrorContents)
End If
End Sub

Public Sub ErrorHandler(ErrorText As String)

WriteLog(“ERROR” + ErrorText)
Me.Invoke(Sub()
Me.ErrorPage.Visible = True          
Me.ErrorLabel.Text = ErrorText                         
End Sub)
BackgroundThread.Abort()
End Sub
End Class

永远不要中止线程。

这使用一个任务和一个手动重置事件。如果没有看到后台任务中的代码,就很难知道可能需要多少停止检查

Public Class Form1
Private BackgroundTask As Task
Private BackgroundTaskRunning As New Threading.ManualResetEvent(True)
Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'Hide Error Page
ErrorPage.Visible = False
ErrorLabel.Visible = False
'Start Background Code
BackgroundTask = Task.Run(Sub() BackgroundCode())
End Sub
Private Sub BackgroundCode()
Try
'<Background code which runs over a number of minutes>
'put stop checks periodically
' e.g.
If Not BackgroundTaskRunning.WaitOne(0) Then Exit Sub 'stop check
Catch ex As Exception
ErrorHandler("Error with BackgroundCode: " + ex.Message)
End Try
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
Dim ErrorFile As String = "C:MyErrorFile.Err"
Dim ErrorContents As String
If File.Exists(ErrorFile) Then
Timer.Enabled = False
ErrorContents = File.ReadAllText(ErrorFile).Trim()
ErrorHandler(ErrorContents)
End If
End Sub
Public Sub ErrorHandler(ErrorText As String)
WriteLog("ERROR" + ErrorText)
Me.Invoke(Sub()
Me.ErrorPage.Visible = True
Me.ErrorLabel.Text = ErrorText
End Sub)
BackgroundTaskRunning.Reset() 'stop task <<<<<<<<<<<<<<<<<<<<<<<<<<<
End Sub
End Class

最新更新