Как динамически создать фоновый рабочий в VB.net - PullRequest
0 голосов
/ 16 июня 2011

У меня есть проект VB.net, в котором для выполнения каких-то задач используется фоновый рабочий.

Теперь я хочу расширить проект, чтобы иметь возможность выполнять несколько задач:)

ПользовательМожно ввести URL-адрес в текстовое поле, и когда пользователь нажимает кнопку разбора, программа создает новую вкладку управления и выводит некоторые данные.

Для этого я использую жестко заданный фоновый рабочий.

Но сейчасЯ хочу запустить несколько фоновых рабочих для этого, поэтому я не могу полагаться на жесткое кодирование фоновых рабочих.

Возможно ли динамическое создание фоновых рабочих.

Я простоЯ понятия не имею, как это настроить, так как я думаю, что мне нужно настроить различные методы и переменные, такие как:

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_DoWork(), Private Sub bw_RunWorkerCompleted() и Private Sub bw_ProgressChanged()

Я думаю, мне нужно объявить фоновых рабочих в некотором массиве, подобном переменной (list / dictionary) ???Кроме того, я понятия не имею, как с этим справиться.

Ответы [ 3 ]

10 голосов
/ 01 сентября 2013

Вот как

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 в каждом обработчике может использоваться для проверки того, какой работник сообщает о прогрессе и т. Д.

6 голосов
/ 16 июня 2011

Хотя BackgroundWorkers могут быть лучшим, самым простым и умным способом многопоточности иногда , я думаю, что вы теперь можете использовать один из других способов многопоточности.

Есть многоспоров / аргументов / троллинга относительно того, какие методы лучше всего использовать в любых обстоятельствах, поэтому я бы посоветовал вам быстро взглянуть на следующие статьи и решить для себя (или если вы не можете найти достаточно хороших ресурсов дляпринять решение, спросить об этом, конечно).

Вы, очевидно, уже смотрели на рабочих на заднем плане, поэтому я не буду перечислять их, и я не буду перечислять всех способов, которыми вы можетенить, просто пара, которая может вас заинтересовать.

Прежде всего, проверьте ThreadPool .Он прост в использовании и довольно эффективно использует ресурсы для повторного использования / повторного использования.Есть некоторые недостатки, такие как использование / удержание слишком большого количества потоков из пула может привести к эксгумации пула, но в простых приложениях это не должно вызывать проблем.

Существует также CLR Async модель , которая поддерживается на удивительном уровне самой платформы, особенно в тех случаях, когда используется какой-либо ресурс ввода-вывода (файл, сеть и т. Д.).

Другим подходом является ParallelКласс , который является одним из моих любимых - я был подключен к многострочному лямбда с тех пор, как он был представлен, и параллель обеспечивает хорошую платформу для этого.

Во всех вышеупомянутых случаях вы можете создать третичныйтемы на лету, без необходимости создавать и поддерживать пул фоновых работников самостоятельно.Трудно сказать, какой подход лучше всего подойдет для вас из представленной информации, но лично я бы рассмотрел пул потоков, если поиск данных для заполнения ваших вкладок не займет слишком много времени.

Надеюсь, это поможет!

1 голос
/ 10 марта 2013

Если я хорошо понимаю ваш вопрос, попробуйте объявить BackgroundWorker на уровне класса:

Friend WithEvents bgw1 As BackgroundWorker

затем в конструкторе класса создаем его экземпляр.

Public Sub New()
  bgw1 = New BackgroundWorker
End Sub

В объявлении уровня класса выберите bgw1, а в раскрывающемся списке событий выберите DoWork, ProgressChanged и RunWorkerCompleted События.

...