我知道Thread.Abort()并不是很安全,但我无法想象下面的情况会导致什么:
Private threadLoadList As Thread
Private Sub LoadList(ByVal argument As Integer)
Try
Refresh_Grid(GET_DATA(argument), argument) 'Fills grid with data loaded from database
Change_Cursor() 'Changes cursor to Cursor.Default
Catch ex As ThreadAbortException
'Do nothing
Catch ex As Exception
Error_log(ex.Message) ' Saves ex.Message in database
End Try
End Sub
Private Sub SomeValueChanged(sender As Object, e As EventArgs) Handles Control.ValueChanged
If Not threadLoadList Is Nothing Then
If threadLoadList.IsAlive Then
threadLoadList.Abort()
End If
End If
Cursor = Cursors.WaitCursor
threadLoadList = New Thread(AddressOf LoadList)
threadLoadList.Start(1)
End Sub
如您所见,用户可以更改某些值(ComboBox),并在结果中更改网格的内容。函数GET_DATA()大约需要10秒,因此用户可能会在刷新网格之前更改Combobox的值 - 这就是之前启动的线程被杀死的原因。
危险吗?如果是的话,你能提出其他解决方案吗?
好的,我理解;)。我尽量避免超时(在某些情况下查询执行时间低于1秒)是否是更好的解决方案:
Private threadLoadList As Thread
Private Changed As Boolean = False
Private Sub LoadList(ByVal argument As Integer)
Try
Dim dt As DataTable = GET_DATA(argument)
'Enter Monitor
If Changed Then
Return
End IF
'Exit Monitor
Refresh_Grid(dt, argument) 'Fills grid with data loaded from database
Change_Cursor() 'Changes cursor to Cursor.Default
'Enter Monitor
Changed = False
'Exit Monitor
Catch ex As ThreadAbortException
'Do nothing
Catch ex As Exception
Error_log(ex.Message) ' Saves ex.Message in database
End Try
End Sub
Private Sub SomeValueChanged(sender As Object, e As EventArgs) Handles Control.ValueChanged
'Enter Monitor
Changed = True
'Exit Monitor
Cursor = Cursors.WaitCursor
Dim t As Thread = New Thread(AddressOf LoadList)
t.Start(1)
End Sub
答案 0 :(得分:1)
首先,除非Refresh_Grid
中有额外的代码,否则我看不到你试图从UI线程以外的线程修改UI元素。这是一个很大的禁忌。 UI元素被设计为仅从UI线程访问,因此尝试在工作线程上修改一个元素将导致不可预测的行为。
关于您对Thread.Abort
的使用,答案是肯定的;有危险。嗯,从某种意义上说,你的应用程序会抛出异常,数据损坏,崩溃,在时空中撕裂等等都是危险的。在中止线程时可能会出现各种各样的故障模式。最好的解决方案是使用协作终止协议而不是进行硬中止。请参阅我的回答here,了解有效方法的简要介绍。