開始する前に、すでにその質問に対する回答がたくさんありますが、何が起こっているのか説明してください。別のスレッドで作成された要素にテキストを設定する方法
基本的にRichTextBox要素にいくつかのテキストを追加したいのですが、ファイル処理からユーザーに各アクションを通知するように私に役立ちますが、テキストはforループを通してRichTextBoxに追加されます。このループは同じクラス "Form1.vb"でループが終了するまでUIがフリーズします。
私はUIのフリーズを避けるためにループを別のスレッドで実行することに決めました。ここで私の問題が始まります。
Form1.vbを
Imports System.Threading
Public Class Form1
Dim myThread As Thread
Private Sub appendMyText()
' Cross-thread operation not valid: Control txtLogger accessed from a thread other than the thread it was created on.
txtLogger.AppendText("Hello World" & vbNewLine)
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
myThread = New Thread(New ThreadStart(AddressOf appendMyText))
myThread.Start()
End Sub
End Class
私は別のスレッドからtxtLogger要素にアクセスすることはできませんので、私はそれが要素にアクセスする方法を私に示しMSDNの例に https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx?cs-save-lang=1&cs-lang=vb#code-snippet-2
を試してみましたデリゲートを使用してスレッドセーフな呼び出しを行います。
だから私の編集したコードは、Form1.vbのコードが実際にこのように動作します
Imports System.Threading
Public Class Form1
Dim myThread As Thread
Delegate Sub AppendMyText(ByVal text As String)
' Add the text to RichTextBox
Private Sub addText(ByVal txt As String)
If txtLogger.InvokeRequired Then
Dim myDelegate = New AppendMyText(AddressOf addText)
Me.Invoke(myDelegate, {txt})
Else
txtLogger.AppendText(txt)
End If
End Sub
' Call the method that add text to RichTextBox
Private Sub threadSafe()
Me.addText("Hello World" & vbNewLine)
End Sub
Private Sub btnTest_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnTest.Click
myThread = New Thread(New ThreadStart(AddressOf threadSafe))
myThread.Start()
End Sub
End Class
で、テキストはリッチテキストボックスに追加されますが、それはすべてのコードが同じクラスになっていますForm1.vb
私のオリジナルプロジェクトでは、forループは別のクラスで実行されていますが、ここでは "Class1.vb"という名前を付けます。
のコード例でClass1.vbの
Public Class Class1
Public Sub count()
Dim i As Integer
For i = 0 To 100
' this method will be executed by thread "myThread"
' how to append text to txtLogger from here?
Debug.WriteLine("Index: {0}", i)
Next
End Sub
End Class
フォームをパラメータとして 'count'メソッドに渡すことができます。 –
私はすでにこの方法を試みました。しかし、別のスレッドから要素に直接アクセスすることはお勧めできません。なぜか分かります!私のプロジェクトは200回以上テキストを追加する必要があり、フォームはそれ自身のスレッドで実行されるため、フォームをパラメータとして渡すと、アプリケーションは応答を停止し、クラッシュします。 –
フォームを使用してカスタムメソッドにアクセスするには、そのメソッドがUI要素へのアクセスを呼び出す限り、依然として可能である必要があります。 –