Zach Johnson
Zach Johnson

Reputation: 2237

Background worker For Loop

Ok I am a bit new to coding and using the backgroundworker so don't judge me too hard.

Basically i am spawning a bunch of background workers and having them do a task. The problem is each background worker is doing the same task. I would like all the spawned background workers to each work on a different task and ignore the task if another background worker has alreday done it.

here is my background worker do work sub:

    Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)
    Threading.Thread.Sleep(5000)
    Dim bgw As BackgroundWorker = DirectCast(sender, BackgroundWorker)
    Dim url As String
    Dim pr As Integer
    Dim prproxy As Integer
    Dim randomLine As Integer

    For rowIndex = 0 To DataGridViewX1.RowCount - 1

        DataGridViewX1.Rows(rowIndex).Cells("Status").Value = "Working"
        url = DataGridViewX1.Rows(rowIndex).Cells("url").Value.ToString



        If SwitchButton1.Value = True Then 'check page rank if proxies are enabled.
            randomLine = RandomNumbers.Next(proxies.TextBoxX1.Lines.Length)
            Dim s As String = proxies.TextBoxX1.Lines(randomLine)
            RandomProxy = Split(s, ":", , CompareMethod.Text)
            pr = PageRank.GooglePageRank.GetPageRankWithProxy(url, RandomProxy(0), RandomProxy(1))
            DataGridViewX1.Rows(rowIndex).Cells("proxy").Value = RandomProxy(0) & ":" & RandomProxy(1)
        Else
            pr = PageRank.GooglePageRank.GetPageRank(url) 'If proxies are not enabled do this.
        End If

        DataGridViewX1.Rows(rowIndex).Cells("PR").Value = pr
        DataGridViewX1.Rows(rowIndex).Cells("Status").Value = "Done"


    Next

End Sub

I'm guessing my problem is in the for loop, but I can't rap my brain around how to do this without it and make each background worker work on a different URL.

Upvotes: 0

Views: 1423

Answers (1)

Thorsten Dittmar
Thorsten Dittmar

Reputation: 56697

The basic problem you're describing has to do with synchronization - a common problem when progrmming multi-threaded applications.

One solution in your case would be to create a queue of tasks to fulfill and have each background worker work on that queue. When a background worker gets a work entry from the queue, it would be removed so there would not be a change of another background worker doing the same thing.

In your case you seem to have a list of URLs which you want to work on. Add these URLs to a queue. The background workers would have a while loop fetching the next entry from the queue until there is no entry left.

The following is C# pseudo-code (I don't speak much VB.NET), but you'll get the picture:

private Queue<string> workerURLs = new Queue<string>();  // this would be a member of the class
private object workerURLsLock = "LOCK"; // This is also a member of the class

Then, add the URLs from your grid to the queue, locked

lock (workerURLsLock)
    for (...)
        workerURLs.Enqueue(...);

After that, start the workers. In the background worker's code, do this:

bool workToDo = true;
while (workToDo)
{
    string nextUrl = "";
    lock (workerURLsLock) // IMPORTANT!! LET NO OTHER THREAD MODIFY THE QUEUE
    {
        nextUrl = workerURLs.Dequeue();
    }

    if (!String.IsNullOrWhitespace(nextUrl))
    {
        // Do the work
    }
    else
    {
        workToDo = false;
    }
}

Upvotes: 1

Related Questions