Excel VSTOアプリケーションのバックグラウンドワーカー、モーダルダイアログによりBGWキャンセルが遅くなる

Excel VSTOアプリケーションでバックグラウンドワーカーを使用してステータスバーとキャンセルボタンを含む進行状況ダイアログボックスをスローして、長時間実行されている計算から逃れるために使用しています。 1つの問題を除いて、本当にうまくいっています。モーダルダイアログを使用したいので、ダイアログの背後にあるUIがモーダルダイアログの代わりにロックされます。 .Show()の代わりに.ShowDialog()を使用すると、フォーム上の[キャンセル]ボタンを押すまですべてが素晴らしい状態になります。デバッガでの処理に続いて、キャンセルが発生します.30秒の範囲内で動作します。フォーム上で.Show()を使用すると、取り消しは直ちに行われます。

私はかなり単純なものを見落としていると確信しています...どんな助けも大いに評価されるでしょう....

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
0

2 答え

私はついに読書の数時間後にポストに戻り、AutoResetEventを実装しました

これは私のために働いた答えであり、どんなApplication.DoEventナンセンスも避けました!

BackgroundWorkerがキャンセルするのを待つ方法

Private _resetEvent As New AutoResetEvent(False)

Private Sub CancelBackGroundWorker(ByVal sender As Object, ByVal e As System.EventArgs)
    BGW.CancelAsync()
    _resetEvent.WaitOne()
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)
            _resetEvent.Set()
        Return
    End If
 _resetEvent.Set()
 End Sub
0
追加された

Application.DoEventsへの通常の呼び出しを追加すると、あなたのコードには何も表示されませんでした。キャンセルクリックは、Windowsメッセージキューに追加されます。 Application.DoEventsを呼び出すと、アプリケーションは未処理のキューメッセージを強制的に処理します。

See also: Application.DoEvents

0
追加された
私は、バックグラウンドワーカーを使用してApplication.DoEventsを使用しないようにしました... DoEventsを使用するときに発生する可能性のある問題を指摘する記事がいくつかあります。 .Show対.ShowDialogを使用すると、クリックイベントが正しく処理されるのはなぜですか?
追加された 著者 GetFuzzy,
ここでの最初の答えを見てください: stackoverflow.com/questions/360789/… (モーダルダイアログは非モーダルダイアログとは大きく異なりますそれはウィンドウメッセージングになると)
追加された 著者 Eddy,