好的我对编码和使用背景工作者有点新意,所以不要太难评判我。
基本上我正在催生一群后勤工作者并让他们完成任务。问题是每个后台工作人员正在执行相同的任务。我希望所有衍生出来的后台工作人员都能完成不同的任务而忽略任务,如果另一个后台工作人员已完成任务。
这是我的后台工作人员做的工作:
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
我猜我的问题是在for循环中,但是如果没有它,我就无法说出如何做到这一点,让每个后台工作者都在不同的URL上工作。
答案 0 :(得分:1)
您所描述的基本问题与同步有关 - 这是编写多线程应用程序时的常见问题。
在您的情况下,一个解决方案是创建一个要完成的任务队列,让每个后台工作程序在该队列上工作。当后台工作者从队列中获取工作条目时,它将被删除,因此不会有另一个后台工作者做同样事情的更改。
在您的情况下,您似乎有一个要使用的URL列表。将这些URL添加到队列中。后台工作程序将有while
循环从队列中获取下一个条目,直到没有条目为止。
以下是C#伪代码(我不会说很多VB.NET),但你会得到图片:
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
然后,将网格中的URL添加到队列中,锁定
lock (workerURLsLock)
for (...)
workerURLs.Enqueue(...);
之后,启动工人。在后台工作者的代码中,执行以下操作:
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;
}
}