2012-01-13 5 views
1

現在実行中のプロセスに応じて、別のプロセスを実行するサブプロシージャがあります。私はこれを行う最も簡単な方法は、キャンペーンの詳細のそれぞれのArrayListを使用することであると考えました& InuseフィールドがInuseフィールドが0または1に設定されているかどうかを確認するために 'Inuse'フィールドを追加しています。一度に処理が行われています&次のスレッドが起動する前に整数が変更されていないので、スレッドが同じキャンペーンを実行しています。VB.NET 2でオーバーラップしない複数のスレッドで異なるプロセスを実行する

開始スレッド間に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 
+1

「プロセス」という単語は特定の意味を持ちますが、これはそうではありません。 –

答えて

2

あなたは待つようにあなたのスレッドを強制的にSyncLockを使用することができます。

クラスレベルので、すべてのスレッドは、あなたのプロセスを開始し、完了したら、それを終了するときsyncLockを使用すると

private myLock as new Object 

同じロックにアクセスします。件名に

SyncLock myLock 
    'process code here 
End SyncLock 

詳しいMSDN情報

+0

私が必要としていたものを正確に動作させるように思えます。ありがとうございました:) – Chris

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()メソッドを変更します。

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

これ以上の使用は必要ありません。また、スレッドwi管理されたThreadPoolによって管理されます!

+0

実行プロセス中のキャンペーンの宣言を適切なvb構文に編集しました。あなたが気にしないことを願っています。 – Jay

+0

ああ、ありがとう!まったく気にしないでください。私は2003年にVB.Netプロジェクトをやりました。それ以来ずっと忘れてしまった。 – NickV

+0

スレッドプールに複数のワーカースレッドがある場合、これは同じ潜在的な問題がまだありますか? – Jay

関連する問題