I'm using a background worker to in an Excel VSTO application to throw up a progress dialog box with a status bar and a cancel button to escape from long running calculations. It's working really well, except for one issue. I'd like to use a Modal Dialog, so that the UI behind the dialog gets locked up, instead of a Modeless Dialog. If I use .ShowDialog() instead of .Show(), everything is great until you hit the Cancel button on the form. Following things in the debugger, the cancellation happens, it just takes somewhere in range of 30 seconds. If I use .Show() on my form, then the cancellation occurs immediately as it should.
I'm sure I'm overlooking something fairly simple... Any help would be much appreciated....
Private WithEvents BGW As BackgroundWorker
Private PD As ProgressDialog
Public Sub BGW_DoCalculation(Mode As RunMode)
'Set the Synchronization Context
System.Threading.SynchronizationContext.SetSynchronizationContext(New WindowsFormsSynchronizationContext())
'Setup the Background Worker
BGW = New BackgroundWorker
BGW.WorkerReportsProgress = True
BGW.WorkerSupportsCancellation = True
'Starts the Background Process
If BGW.IsBusy = False Then
BGW.RunWorkerAsync(Mode)
Else
Exit Sub
End If
'Start the Process Dialog Box
PD = New ProgressDialog
'Add a handler to cancel background worker
AddHandler PD.Cancel_Button.Click, AddressOf CancelBackGroundWorker
PD.ShowDialog()
End Sub
Private Sub CancelBackGroundWorker(sender As Object, e As System.EventArgs)
BGW.CancelAsync()
End Sub
Private Sub BGW_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BGW.DoWork
If BGW.CancellationPending = False Then
Dim Mode As RunMode = CType(e.Argument, RunMode)
LongRunningCalc(Mode)
Else
e.Cancel = True
Return
End If
End Sub
Private Sub BGW_WorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BGW.RunWorkerCompleted
PD.Dispose()
BGW.Dispose()
End Sub
Private Sub BGW_WorkerProgress(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BGW.ProgressChanged
PD.ProgressBar1.Maximum = 100
If Not BGW.CancellationPending Then
PD.ProgressBar1.Value = e.ProgressPercentage
PD.PercentCompleteLabel.Text = e.ProgressPercentage & "%"
'Update the message Label
PD.MessageLabel.Text = e.UserState.ToString
End If
End Sub
'This is shortened for the posting...
Public Sub LongRunningCalc(ByVal Mode As RunMode)
'Do long running calc - obviously this isn't the calc ;)
For i = 0 to 1000000000000000
i+1
End For
If BGW.CancellationPending = True Then
'Report Progress
BGW.ReportProgress(CInt(((Scen) / TotalScen) * 100), "Canceling Calculation, Please Wait")
'Output the scenarios that have been calculated...
Call Globals.ThisWorkbook.OutScen(Scen, Count)
Return
End If
End Sub