Безопасность потоков, Дизайн приложений - PullRequest
1 голос
/ 25 июля 2011

У меня есть консольное приложение, которое просматривает очередь и обрабатывает каждую запись в виде данных.Каждый процесс занимает много времени (подключение к удаленному веб-сайту, загрузка файлов, их чтение и добавление в базу данных).Я пытаюсь реализовать многопоточность ради скорости, но у меня возникают проблемы с многопоточностью.(Выполнение задания занимает около 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

1 Ответ

0 голосов
/ 25 июля 2011

iThread = iThread + 1 не является поточно-ориентированным.
Вместо этого следует вызвать Interlocked.Increment.

Если вы используете .Net 4.0, вам следует использовать новый Task API вместо ThreadPool;затем вы можете позвонить Task.WaitAll.

...