在这种情况下如何避免Thread.Abort()?

时间:2013-07-23 08:49:45

标签: vb.net multithreading

我知道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

1 个答案:

答案 0 :(得分:1)

首先,除非Refresh_Grid中有额外的代码,否则我看不到你试图从UI线程以外的线程修改UI元素。这是一个很大的禁忌。 UI元素被设计为仅从UI线程访问,因此尝试在工作线程上修改一个元素将导致不可预测的行为。

关于您对Thread.Abort的使用,答案是肯定的;有危险。嗯,从某种意义上说,你的应用程序会抛出异常,数据损坏,崩溃,在时空中撕裂等等都是危险的。在中止线程时可能会出现各种各样的故障模式。最好的解决方案是使用协作终止协议而不是进行硬中止。请参阅我的回答here,了解有效方法的简要介绍。