vb.net中的线程问题

时间:2015-03-12 13:17:58

标签: vb.net multithreading

背景: 我有一个程序正在处理大量的数据库记录,并生成要执行的任务。 (在这种情况下,在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作为新线程.....

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

任何人都可以帮我告诉我哪里出错了吗? 欢呼声。

1 个答案:

答案 0 :(得分:1)

线程没有公共构造函数,需要调用Thread.Start。我建议你不要这样做。当您了解多线程编程时,编写线程安全的代码非常棘手。

例如,在您的代码中,您可以从两个不同的线程修改队列而不进行锁定。队列不是线程安全的,您可以破坏队列。您应该锁定对它的访问权限或使用 线程安全的ConcurrentQueue。另一个错误是尝试从另一个线程修改TextBox - 这将导致异常,因为只允许UI线程修改UI控件。

更好的选择是使用DataFlow库中已经执行了所需操作的ActionBlock类:队列请求并在一个或多个单独的线程中处理它们。

您的代码可以像这样简单:

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()

默认情况下,一次只处理一个路径。要处理多个路径,您需要传递具有所需MaxDegreeOfParallelism的ExecutionDataflowBlockOptions对象:

Dim options=New ExecutionDataflowBlockOptions() With { .MaxDegreeOfParallelism=5}
Dim myFileWorker=New ActionBlock(Of String) Function(path) DoSomething(path),options)