在多线程中运行不同的进程而不在VB.NET中重叠2

时间:2012-01-13 18:49:43

标签: vb.net multithreading visual-studio threadpool

我有一个子程序,我想运行一个不同的进程,具体取决于当前正在运行的程序。我认为最简单的方法是使用每个广告系列详细信息的ArrayList。添加一个'Inuse'字段来检查Inuse字段是否设置为0或1.我遇到的问题是,当运行该过程时,它会立即发生。在下一个线程开始之前,整数没有被更改,因此我的线程正在运行相同的广告系列。

我尝试通过在起始线程之间添加Thread.Sleep(100)延迟来避免此问题,但这导致了完全相同的问题。

这是我想要做的一个例子:

    Imports System.Threading

Public Class Form1

    Private Campaigns As New ArrayList
    Private ProcessRunning As Boolean = False
    Friend StopProcess As Boolean = False

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i = 0 To Campaigns.Count - 1
            Dim objNewThread As New Thread(AddressOf RunProcess)
            objNewThread.IsBackground = True
            objNewThread.Start()
        Next
    End Sub

    Private Sub UpdateCells(ByVal CampID As Integer, ByVal Column As String, ByVal newText As String)
        Dim CellItemNum As Integer
        If Column = "Status" Then CellItemNum = 4
        DataGridView2.Rows(CampID).Cells.Item(CellItemNum).Value = newText
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        For i As Integer = 0 To 10
            Campaigns.Add({Campaigns.Count(), "Campaign " & i, "Keywords " & i, "Link " & i, 5, True, 0, 0})
        Next
        DataGridView2.Rows.Clear()
        For Each Campaign In Campaigns
            DataGridView2.Rows.Add(New String() {Campaign(1), Campaign(2), Campaign(3), Campaign(6), ""})
        Next
    End Sub

    Private Sub RunProcess()
        ' Set Variables
        Dim CampID As Integer
        Dim CampName As String
        Dim Keywords As String
        Dim Link As String
        Dim CheckEvery As Integer
        Dim OkToUse As Boolean
        Dim Sent As Integer
        ' Find A Free Campaign
        For i As Integer = 0 To Campaigns.Count - 1
            ' Check If Inuse
            If Campaigns(i)(7) = 1 Then Continue For Else Campaigns(i)(7) = 1 ' This Line Sets Campaign To Inuse
            ' Most of the time only campaign(0) and campaign(1) are selected & multiple threads are running them instead of choosing unique campaigns
            ' Set Campaign Details
            CampID = Campaigns(i)(0)
            CampName = Campaigns(i)(1)
            Keywords = Campaigns(i)(2)
            Link = Campaigns(i)(3)
            CheckEvery = Campaigns(i)(4)
            OkToUse = Campaigns(i)(5)
            Sent = Campaigns(i)(6)
            ' Start Process
            UpdateCells(CampID, "Status", "Looking Up New Links (" & CampID & ")")
            Exit For
        Next
        While StopProcess = False
            Thread.Sleep(1000)
            UpdateCells(CampID, "Status", "Running Process (" & CampID & ")")
            Thread.Sleep(1000)
            For i = 0 To CheckEvery
                UpdateCells(CampID, "Status", "Re-Checking In " & (CheckEvery - i) & " Seconds")
                Thread.Sleep(1000)
            Next
        End While
        ' Closing Processes
        Campaigns(CampID)(7) = 0
    End Sub
End Class

2 个答案:

答案 0 :(得分:2)

您可以使用SyncLock强制线程等待。

类级别,所以所有线程都访问相同的锁

private myLock as new Object

然后在开始流程时使用syncLock,并在完成后结束。

SyncLock myLock
  'process code here
End SyncLock

有关该主题的更多MSDN信息

答案 1 :(得分:1)

尝试查看QueueUserWorkItem():

Private Sub Button1_Click(ByVal sender As System.Object,
    ByVal e As System.EventArgs) Handles Button1.Click
    For i = 0 To Campaigns.Count - 1
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf RunProcess), Campaigns[i])
    Next
End Sub

然后更改RunProcess()方法以包含工作项发送的Campaign对象:

Private Sub RunProcess(ByVal o As System.Object)
    ' Process the Campaign
    Dim campaign As Campaign = Ctype(o, Campaign)
End Sub

不需要使用,加上线程将由托管的ThreadPool管理!