Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 循环的后台工作程序_Vb.net_Multithreading_Visual Studio 2010_Backgroundworker - Fatal编程技术网

Vb.net 循环的后台工作程序

Vb.net 循环的后台工作程序,vb.net,multithreading,visual-studio-2010,backgroundworker,Vb.net,Multithreading,Visual Studio 2010,Backgroundworker,好的,我对编码和使用backgroundworker有点陌生,所以不要对我太苛刻 基本上,我是在培养一群背景工作者,让他们完成一项任务。问题是每个后台工作人员都在执行相同的任务。我希望所有产生的后台工作人员都在不同的任务上工作,如果其他后台工作人员已经完成了任务,则忽略该任务 这是我的背景工作人员do work sub: Private Sub bgw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Threa

好的,我对编码和使用backgroundworker有点陌生,所以不要对我太苛刻

基本上,我是在培养一群背景工作者,让他们完成一项任务。问题是每个后台工作人员都在执行相同的任务。我希望所有产生的后台工作人员都在不同的任务上工作,如果其他后台工作人员已经完成了任务,则忽略该任务

这是我的背景工作人员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

我猜我的问题在for循环中,但我无法思考如何在没有它的情况下做到这一点,并让每个后台工作人员在不同的URL上工作。

您描述的基本问题与同步有关,这是编程多线程应用程序时的常见问题

在您的案例中,一个解决方案是创建一个要完成的任务队列,并让每个后台工作人员在该队列上工作。当一个后台工作人员从队列中获得一个工作条目时,它将被删除,这样另一个后台工作人员就不会做同样的事情

在你的例子中,你似乎有一个你想要处理的URL列表。将这些URL添加到队列中。后台工作人员在从队列中获取下一个条目时将有一个
循环,直到没有剩余条目为止

下面是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
之后,开始工作。在后台工作代码中,执行以下操作:

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;
    }
}

您描述的基本问题与同步有关,这是编程多线程应用程序时的常见问题

在您的案例中,一个解决方案是创建一个要完成的任务队列,并让每个后台工作人员在该队列上工作。当一个后台工作人员从队列中获得一个工作条目时,它将被删除,这样另一个后台工作人员就不会做同样的事情

在你的例子中,你似乎有一个你想要处理的URL列表。将这些URL添加到队列中。后台工作人员在从队列中获取下一个条目时将有一个
循环,直到没有剩余条目为止

下面是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
之后,开始工作。在后台工作代码中,执行以下操作:

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;
    }
}

嘿,谢谢,这很有帮助。我现在的问题是,我不知道如何传递后台工作人员正在处理的gridview行,以便它能够将数据插入到网格中,例如:DataGridViewX1.Rows(rowIndex).Cells(“Status”).Value=“working”我将继续调整它,但如果您对此有任何了解,那太棒了。当然,你不仅可以在
字典中添加字符串,还可以添加对象。您可以创建一个小型帮助器类,该类具有URL的成员和类型为
DataGridViewRow
的成员。然后,工人将两者兼得。根据框架版本的不同,还可以使用
Tuple
。但是,请注意,在跨线程操作中访问
DataGridViewRow
(即更改其值)可能会导致错误。使用
this.Invoke
确保在GUI线程中执行此类更新。感谢您的帮助。最后,我在将URL添加到synchlocked队列的同一个循环中将索引添加到列表中,所有UI更新都是在bgw_ProgressChanged事件中通过将索引作为参数传递来完成的(据我所知,这是正确的方式)。一切似乎都很好。嘿,谢谢,这很有帮助。我现在的问题是,我不知道如何传递后台工作人员正在处理的gridview行,以便它能够将数据插入到网格中,例如:DataGridViewX1.Rows(rowIndex).Cells(“Status”).Value=“working”我将继续调整它,但如果您对此有任何了解,那太棒了。当然,你不仅可以在
字典中添加字符串,还可以添加对象。您可以创建一个小型帮助器类,该类具有URL的成员和类型为
DataGridViewRow
的成员。然后,工人将两者兼得。根据框架版本的不同,还可以使用
Tuple
。但是,请注意,在跨线程操作中访问
DataGridViewRow
(即更改其值)可能会导致错误。使用
this.Invoke
确保在GUI线程中执行此类更新。感谢您的帮助。在将URL添加到synchlocked队列的同一个循环中,我将索引添加到列表中,所有UI更新都是在bgw_ProgressChanged事件中通过将索引作为参数传递来完成的(据我所知,这是正确的方法)。一切似乎都很好。