2011-07-25 225 views
1

我有一个控制台应用程序,它循环访问队列并处理数据表中的每条记录。每个过程都很耗时(连接到远程网站,下载文件,读取它们并将它们添加到数据库中)。我试图为了速度而实现线程化,但是遇到了交叉线程问题。 (这项工作需要8小时左右才能运行,直到运行几个小时才开始交叉线程。)线程安全,应用程序设计

我想弄清楚如何让我的代码线程安全。我不更新或依赖任何非本地变量,并且我不需要返回任何内容。我试过锁定哪些作品,但是击败了多个线程的目的。我还需要寻找其他什么东西?

Module Module1 

Dim iThread As Integer 
Dim manualEvents(4) As ManualResetEvent 
Private lockObject As New Object() 

Sub Main() 
    ' some prep work 

    For i = 0 To 4 
     manualEvents(i) = New ManualResetEvent(False) 
     ThreadPool.QueueUserWorkItem(AddressOf DoOne) 
    Next 

    For Each handle As WaitHandle In manualEvents 
     handle.WaitOne() 
    Next 

    ' some cleaning 
End Sub 


Private Sub DoOne() 
    If QueryQueue Then 
     DoOne() 
    Else 
     manualEvents(iThread).Set() 
     iThread = iThread + 1 
    End If 
End Sub 


Public Function QueryQueue() As Boolean 

    Dim dt As DataTable = GetData() 
    If dt.Rows.Count > 0 Then 
     With dt 
      Dim Variable1 As String = .Rows(0).Item("Variable1") 
      Dim Variable2 As String = .Rows(0).Item("Variable2") 
      Dim Variable3 As Integer = .Rows(0).Item("Variable3") 
      ProcessRecord(Variable1, Variable2, Variable3) 
     End With 
     Return True 
    Else 
     Return False 
    End If 

End Function 

Public Sub ProcessRecord(ByVal Variable1 As String, ByVal Variable2 As String, ByVal Variable3 As Integer) 
    AnotherMethod(Variable1, Variable2, Variable3) 
End Sub 

Public Sub AnotherMethod(ByVal Variable1 As String, ByVal Variable2 As String, ByVal Variable3 As Integer) 
    AnotherMethod2(Variable1, Variable2, Variable3) 
End Sub 

Public Sub AnotherMethod2(ByVal Variable1 As String, ByVal Variable2 As String, ByVal Variable3 As Integer) 
    AnotherMethod3(Variable1, Variable2, Variable3) 
End Sub 

' ... etc. 

End Module 
+0

可能的重复[使用ThreadPool.QueueUserWorkItem的线程排序](http://stackoverflow.com/questions/1833673/ordering-of-thread-using-threadpool-queueuserworkitem) –

+0

@ 7lan:接受的问题答案我链接到应该为您提供一个完整的实现你正在寻找什么。如果您想了解更多信息或更全面地了解正在发生的事情,我可以给您一个关于我在这个主题上撰写的博客文章的链接。 –

+0

谢谢亚当,我会看看另一个问题。我也很想看到你的博客文章。 – 7Ian

回答

0

iThread = iThread + 1不是线程安全的。
您应该改用Interlocked.Increment

如果您使用.Net 4.0,则应该使用新的Task API而不是ThreadPool;您可以致电Task.WaitAll