1

私のコードは機能しますが、CheckForIllegalCrossThreadCalls を false に設定すると、バックグラウンド ワーカーに何らかの副作用が生じると思われるため、何をしたか疑問です。ここに私のサンプルコードがあります:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False

End Sub

Private Sub go_Click(sender As Object, e As EventArgs) Handles go.Click

    Try
        If BackgroundWorker1.IsBusy <> True Then
            BackgroundWorker1.RunWorkerAsync()
            resetevent.Set()
        End If

    Catch ex As Exception

    End Try

End Sub


Private Sub BackgroundWorker1_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    Do

    Label1.Text = x
Label2.Text = Label1.Text
Label3.Text = Label2.Tex
Label4.Text = Label3.Text
Label5.Text = Label4.Text

    x+=1
    Loop While (x < 100)


End Sub

Private Sub BackgroundWorker1_ProgressChanged(sender As System.Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
    Try



    Catch ex As Exception

    End Try
End Sub

Private Sub BackgroundWorker1_Completed(sender As System.Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    Try

    Catch ex As Exception

    End Try
End Sub

CheckForIllegalCrossThreadCalls を False に設定せずに、backgroundworker 内のラベルに値を設定する方法はありますか? カウンターの制限にまだ達していなくても、ループが突然停止するというバグがプログラムで発生したためです。

4

3 に答える 3

8

メソッドを作成する

  Private Sub setLabelTxt(ByVal text As String, ByVal lbl As Label)
    If lbl.InvokeRequired Then
        lbl.Invoke(New setLabelTxtInvoker(AddressOf setLabelTxt), text, lbl)
    Else
        lbl.Text = text
    End If
End Sub
Private Delegate Sub setLabelTxtInvoker(ByVal text As String, ByVal lbl As Label)

DoWork で setLabelTxt を呼び出します。

編集: 私は今少し忙しいので、参考文献を使って少し後で説明を追加します. 私もあなたの問題を抱えていましたが、これは私にとってはうまくいきました。

編集:

"ワーカー スレッドからコントロールに安全にアクセスする方法は、委任を使用することです。 まず、コントロールの InvokeRequired プロパティをテストします。これにより、コントロールに安全にアクセスできるかどうかがわかります。InvokeRequired は、Control クラスの数少ないメンバーの 1 つです。プロパティが True の場合、現在のメソッドはコントロールのハンドルを所有するスレッド以外のスレッドで実行されているため、コントロールにアクセスするには呼び出しが必要です。

呼び出しは、コントロールの Invoke または BeginInvoke メソッドを呼び出すことによって実行されます。メソッドへの参照を含むオブジェクトであるデリゲートを作成します。現在のメソッドへの参照を作成することをお勧めします。次に、そのデリゲートを Invoke または BeginInvoke メソッドに渡します。これは基本的に、今度はコントロールのハンドルを所有するスレッドで、参照されたメソッドを再度呼び出します。」

ソース: jmcilhinney投稿ワーカー スレッドからのコントロールへのアクセス http://www.vbforums.com/showthread.php?498387-Accessing-Controls-from-Worker-Threads

私も初心者なので、彼以上にうまく説明することはできません

于 2013-09-17T08:51:54.510 に答える
3

イベント中はProgressChanged、MSDN ドキュメントに記載されている UI にアクセスできます。

ProgressChanged イベント ハンドラーは、BackgroundWorker を作成したスレッドで実行されます。

したがって、BackGroundWorkerUI スレッドで を作成した場合は、UI を更新できるため、CheckForIllegalCrossThreadCalls

ソース:

MSDN バックグラウンド ワーカー

于 2013-09-17T08:45:42.087 に答える