Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.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_Backgroundworker - Fatal编程技术网

如何在VB.net中动态创建后台工作程序

如何在VB.net中动态创建后台工作程序,vb.net,backgroundworker,Vb.net,Backgroundworker,我有一个VB.net项目,它使用后台工作者来做一些事情 现在我想扩展项目,使其能够完成多种工作:) 用户可以在文本框中输入URL,当用户单击parse按钮时,程序将创建一个新的tabcontrol并输出一些数据 我使用了一个硬编码的后台工作程序 但是现在我想运行多个后台工作人员来完成这项工作,所以我不能依赖于对后台工作人员进行硬编码 是否可以动态创建后台工作人员 我只是不知道如何设置,因为我认为我需要设置不同的方法和变量,如: Private bw As BackgroundWorker = N

我有一个VB.net项目,它使用后台工作者来做一些事情

现在我想扩展项目,使其能够完成多种工作:)

用户可以在文本框中输入URL,当用户单击parse按钮时,程序将创建一个新的tabcontrol并输出一些数据

我使用了一个硬编码的后台工作程序

但是现在我想运行多个后台工作人员来完成这项工作,所以我不能依赖于对后台工作人员进行硬编码

是否可以动态创建后台工作人员

我只是不知道如何设置,因为我认为我需要设置不同的方法和变量,如:

Private bw As BackgroundWorker = New BackgroundWorker
bw.WorkerReportsProgress = True
bw.WorkerSupportsCancellation = True
AddHandler bw.DoWork, AddressOf bw_DoWork
AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted
bw.RunWorkerAsync()
Private Sub bw\u DoWork()
Private Sub bw\u runworker completed()
Private Sub bw\u ProgressChanged()


我想我需要在某种类似数组的变量(
list
/
dictionary
)中声明后台工作程序???另外,我不知道如何解决这个问题。

虽然后台工作有时是多线程的最佳、最简单和最智能的方式,但我认为您现在可能会考虑使用其他多线程方式之一

关于在每种情况下使用哪种方法最好,有很多争论/争论/抱怨,所以我给你的建议是快速阅读以下文章,然后自己决定(或者如果你找不到足够好的资源来做决定,当然可以问下去)

你显然已经看过幕后工作人员了,所以我不会列出他们,也不会列出所有你可以使用的方法,只是一些你可能感兴趣的方法

首先,请查看下面的示例。它易于使用,并且相当好地利用了回收/再利用资源。有一些缺点,例如使用/持有池中过多线程可能会导致池溢出,但在简单的应用程序中,这不应该是一个问题

另外还有一个框架,它在大量框架本身中都得到了支持,特别是在涉及某种形式的IO资源(文件、网络等)的情况下

另一种方法是并行,这是我最喜欢的方法之一——自从引入多行lambda以来,我一直对它着迷,而并行为这样做提供了一个很好的平台

在上述所有情况下,您都可以动态创建第三线程,而无需自己创建和维护后台工作线程池。很难说哪种方法能从提供的信息中为您提供最佳的效果,但我个人认为,如果数据的填充填充标签的话,线程池不会花太长时间。
希望有帮助

如果我能很好地理解您的问题,请尝试在班级级别将
BackgroundWorker
声明为:

Friend WithEvents bgw1 As BackgroundWorker
然后在类内构造函数实例化它

Public Sub New()
  bgw1 = New BackgroundWorker
End Sub
在类级声明中选择
bgw1
,其事件下拉部分选择
DoWork
ProgressChanged
RunWorkerCompleted
事件。

以下是如何操作的

Public Class Form
    Private Workers() As BackgroundWorker
    Private NumWorkers = 0

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        NumWorkers = NumWorkers + 1
        ReDim Workers(NumWorkers)
        Workers(NumWorkers) = New BackgroundWorker
        Workers(NumWorkers).WorkerReportsProgress = True
        Workers(NumWorkers).WorkerSupportsCancellation = True
        AddHandler Workers(NumWorkers).DoWork, AddressOf WorkerDoWork
        AddHandler Workers(NumWorkers).ProgressChanged, AddressOf WorkerProgressChanged
        AddHandler Workers(NumWorkers).RunWorkerCompleted, AddressOf WorkerCompleted
        Workers(NumWorkers).RunWorkerAsync()
    End Sub

End Class
然后是处理者

Private Sub WorkerDoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs)
    ' Do some work
End Sub

Private Sub WorkerProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs)
    ' I did something!
End Sub

Private Sub WorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs)
    ' I'm done!
End Sub

想象一下,多线程可以如此简单。除非你有1000名工人,否则这很有效。每个处理程序中的sender参数可用于检查报告进度的工作人员等。

如果我错了,请纠正我,但是
ReDim
关键字是否创建新数组并将其分配给
工作人员
?根据我的知识和以前使用
ReDim
的经验,每次单击按钮时,阵列都将被销毁,并使用新的维度重新创建,然后新的后台工作人员将被分配到最后一个元素,
Workers
阵列将不包含以前创建的任何后台工作人员。如果您想保留所有这些,是否应该使用
ReDim-Preserve-Workers(NumWorkers)
?如果您有此代码并想停止
CancelAsync()
您将如何做?。我希望在类中使用这段代码,这样我就可以在我的程序中复制它,而不必重写它。但我现在唯一挣扎的是我不能“阻止”工人。如果我按下一个按钮两次,而第一个按钮没有被称为worker finishing,那么我有两个worker在做同样的事情。我想在启动第二个worker之前取消第一个worker.Parallel.For和Parallel.ForEach是在我经常遇到的许多简单情况下让多线程工作进行的非常简单的方法,实现它们的工作量几乎为零。我在VB 2013上使用它们。我认为SyncLock语句是一个VB专用语句,与其他锁实现相比,它进一步简化了代码。@evilspoons
SyncLock
在c中转换为
lock
,如果我没记错的话()