背景:私は、多くのデータベースレコードを処理し、実行するタスクを生成するプログラムを持っています。(この場合、ADでユーザーアカウントを作成します)。これの一部は、プロファイルとホームディレクトリ用のユーザーディレクトリを作成し、それらにアクセス許可を設定することです。これは、広告アカウントがすべてのDCに複製されるまで待つ必要があります。
したがって、私のプログラムには、ディレクトリの作成を担当する別のスレッドがあり、メインスレッドから入力されたキューを処理します。
私はスレッド化についていくつかの調査を行い、次のコードパターンを考え出しました。
Imports System.Threading
Public Class Form1
Dim worker As Object
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
worker = New workerObj(AddressOf resultcallback)
Dim t As New Thread(AddressOf worker.mainloop)
End Sub
Public Sub resultcallback(ByVal item As String)
Outbox.AppendText(item)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
worker.addItem(inbox.Text)
End Sub
End Class
Public Delegate Sub resultcallback(ByVal item As String)
Public Class workerObj
Private myQueue As New Queue(Of String)
Private myCallback As resultcallback
Dim item As String = "nout"
Public Sub New(ByVal callbackdelegate As resultcallback)
myCallback = callbackdelegate
End Sub
Public Sub mainloop()
While True
If myQueue.Count > 0 Then
item = myQueue.Dequeue()
myCallBack(item)
End If
Thread.Sleep(5000)
End While
End Sub
Public Sub addItem(ByVal item As String)
myQueue.Enqueue(item)
End Sub
End Class
問題:行Dim t as new Thread....。
Error 1 Overload resolution failed because no accessible 'New' is most specific for these arguments:
'Public Sub New(start As System.Threading.ParameterizedThreadStart)': Not most specific.
'Public Sub New(start As System.Threading.ThreadStart)': Not most specific. n:\visual studio 2013\Projects\ThreadTest\ThreadTest\Form1.vb 7 13 ThreadTest
誰かが私がどこで間違っているのか教えてもらえますか?乾杯。
スレッドにはパブリックコンストラクターがないため、Thread.Startを呼び出す必要があります。ただし、そうしないことをお勧めします。マルチスレッドプログラミングについて知っている場合、スレッドセーフなコードを書くのは十分に注意が必要です。
たとえば、コードでは、ロックせずに2つの異なるスレッドからキューを変更します。キューはスレッドセーフではないため、キューが破損する可能性があります。アクセスをロックするか、スレッドセーフなConcurrentQueueを使用する必要があります。別のエラーは、別のスレッドからTextBoxを変更しようとしています。これは、UIスレッドのみがUIコントロールの変更を許可されているため、例外につながります。
ただし、より良いオプションは、DataFlowライブラリのActionBlockクラスを使用することです。これは、要求をキューに入れ、1つ以上の個別のスレッドで処理します。
コードは次のように単純にすることができます。
Dim myFileWorker=New ActionBlock(Of string)(Function(path) =>DoSomething(path))
For Each somePath As String in ListWithManyPaths
myFileWorker.Post(somePath)
Next somePath
myFileWorker.Complete()
myFileWorker.Completion.Wait()
デフォルトでは、一度に1つのパスのみが処理されます。複数のパスを処理するには、目的のMaxDegreeOfParallelismを指定してExecutionDataflowBlockOptionsオブジェクトを渡します。
Dim options=New ExecutionDataflowBlockOptions() With { .MaxDegreeOfParallelism=5}
Dim myFileWorker=New ActionBlock(Of String) Function(path) DoSomething(path),options)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加