我有一个子程序,我想运行一个不同的进程,具体取决于当前正在运行的程序。我认为最简单的方法是使用每个广告系列详细信息的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
答案 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管理!