我有一个BackgrounWorker
从名为ExcelOutput
的自定义类中调用vairous方法。以下功能有效,但不允许我检查取消。
Private Sub bw_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs)
Dim UserDump As New CurrentUserDumpInfo(Me.MainForm.ConfigForm) ' Create a new instance of the CurrentUserDumpInfo
Dim Excel As New ExcelOutput(Me) ' Create a new instance of the ExcelOutput
Dim FirstRow As Integer = 4 ' The row on which the output should start
Dim CurrentRow As Integer ' The currnet row on which the output shoud continue
'** Prepare the CurrentUserDumpInfo and the ExcelOutput *'
Call UserDump.prepare()
Call Excel.Prepare()
CurrentRow = Excel.OutputGroup("General", UserDump.lstGeneralHeaders, UserDump.lstGeneralData, FirstRow)
CurrentRow = Excel.OutputGroup("Address", UserDump.lstAddressHeaders, UserDump.lstAddressData, CurrentRow + 2)
Call Excel.AutofitContents(4, CurrentRow)
Call Excel.AlignCells(4, CurrentRow)
Call Excel.StyleWorksheet()
Call Excel.MakeSafeCopy()
Call Excel.LockWorksheet()
Call Excel.Finish(UserDump.CurrentUser.FullName)
End Sub
为此,我设置了上面列出的每个方法来检查错误(使用Try/Catch
),如果有错误,我设置 bw.WorkerSupportsCancellation = True
bw.CancelAsync()
方法(您会注意到我在启动Me
实例时传递了ExcelOutput
,这样就可以了。)
这个方法有效,但为了完全实现它,我必须将每个调用包装在If
块中,这样会使代码非常长且难以阅读(每个调用从1行到6行) -
If bw.CancellationPending = True Then
e.Cancel = True
Exit Sub
Else
CurrentRow = Excel.OutputGroup("General", UserDump.lstGeneralHeaders, UserDump.lstGeneralData, 4)
End If
有没有更好的方法来做到这一点,既可以保持代码简短,又可以提供取消检查的功能?感谢。
感谢下面的回答,这里是我正在使用的确切bw_DoWork()
方法,它完全符合我的要求 -
Private Sub bw_DoWork(ByVal sender As Object,
ByVal e As DoWorkEventArgs)
Dim UserDump As New CurrentUserDumpInfo(Me.MainForm.ConfigForm) ' Create a new instance of the CurrentUserDumpInfo
Dim Excel As New ExcelOutput(Me) ' Create a new instance of the ExcelOutput
Dim FirstRow As Integer = 4 ' The row on which the output should start
Dim CurrentRow As Integer ' The currnet row on which the output shoud continue
Dim Counter As Integer = 0
While Not bw.CancellationPending = True
Select Case Counter
Case 0 : Call UserDump.prepare() : Exit Select ' Prepare the CurrentUserDumpInfo object ready for use
Case 1 : Call Excel.Prepare() : Exit Select ' Prepare the ExcelOutput object ready for use
Case 2 : CurrentRow = Excel.OutputGroup("General", UserDump.lstGeneralHeaders, UserDump.lstGeneralData, FirstRow) : Exit Select
Case 3 : CurrentRow = Excel.OutputGroup("Address", UserDump.lstAddressHeaders, UserDump.lstAddressData, CurrentRow + 2) : Exit Select
Case 4 : CurrentRow = Excel.OutputGroup("Account", UserDump.lstAccountHeaders, UserDump.lstAccountData, CurrentRow + 2) : Exit Select
Case 5 : CurrentRow = Excel.OutputGroup("Profile", UserDump.lstProfileHeaders, UserDump.lstProfileData, CurrentRow + 2) : Exit Select
Case 6 : Call Excel.AutofitContents(4, CurrentRow) : Exit Select
Case 7 : Call Excel.AlignCells(4, CurrentRow) : Exit Select
Case 8 : Call Excel.StyleWorksheet() : Exit Select
Case 9 : Call Excel.MakeSafeCopy() : Exit Select
Case 10 : Call Excel.LockWorksheet() : Exit Select
Case 11 : Call Excel.Finish(UserDump.CurrentUser.FullName) : Exit Select
Case Else : Exit While
End Select
Counter += 1
End While
'** Check to see if the BackgroundWorker should be cancelled *'
If bw.CancellationPending = True Then e.Cancel = True
End Sub
答案 0 :(得分:2)
在DoWork事件中没有使用try / catch的“常见”规则。例外情况是您要处置或清理对象。如果发生错误,它将在RunWorkerCompleted
事件(e.Error)中可用。
Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bw.DoWork
Dim obj As IDisposable = Nothing
Dim [error] As Exception = Nothing
Try
obj = New Control()
Throw New Exception("Simulated exception")
Catch ex As Exception
[error] = ex
Finally
If (Not obj Is Nothing) Then
obj.Dispose()
obj = Nothing
End If
End Try
If (Not [error] Is Nothing) Then
Throw [error]
End If
End Sub
话虽如此,您可以尝试在While Loop
中完成工作,并在每个周期后检查取消。
Private Sub bw_DoWork(sender As Object, e As DoWorkEventArgs) Handles bw.DoWork
Dim worker As BackgroundWorker = DirectCast(sender, BackgroundWorker)
Dim num As Integer = Nothing
Dim obj As IDisposable = Nothing
Dim [error] As Exception = Nothing
Try
'TDOD: obj = New IDisposable ()
num = 0
While (Not e.Cancel)
Select Case num
Case 0
'Do somthing
Exit Select
Case 1
'Do somthing
Exit Select
Case 2
'Do somthing
Exit Select
Case Else
Exit While
End Select
num += 1
e.Cancel = worker.CancellationPending
End While
Catch ex As Exception
[error] = ex
Finally
If (Not obj Is Nothing) Then
obj.Dispose()
obj = Nothing
End If
End Try
If (Not [error] Is Nothing) Then
Throw [error]
ElseIf (Not e.Cancel) Then
'TODO: e.Result = Nothing
End If
End Sub