Вопрос

Я хочу начать работу в новом потоке или использовать backgroundworker для этого, но не делал этого раньше и спрашиваю вас, каким способом мне следует это сделать.

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

У меня есть класс clsDownload, который обрабатывает все и возвращает события обратно, но как мне реализовать фоновую обработку?

Должен ли я использовать System.ComponentModel.BackgroundWorker внутри класса или создать какую-то оболочку, которая обрабатывает это, или использовать какие-то другие потоки?

Спасибо.

Редактировать: Я не понимаю, как реализовать мою загрузку в backgroundworker, любой небольшой пример был бы очень хорош.Пример на msdn далеко меня не завел.

У меня есть класс загрузки, который имеет StartDownload-функцию.Должен ли я использовать backgroundworker В классе или в вызывающем?"чувствую себя глупо"

Это было полезно?

Решение

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

Вот как может выглядеть ваш класс работы:

Private m_bwMain As BackgroundWorker

Public Sub New(ByVal bwMain As BackgroundWorker)
    m_bwMain = bwMain

    'additional setup code here
End Sub

Чтобы запустить задание, вы должны сделать что-то вроде этого в обработчике события Click вашей кнопки Start Download:

lblStatus.Text = "Initializing ..."
bgwMain.RunWorkerAsync(someFileName)

Я объявляю свой класс job как закрытый элемент текущей формы, затем создаю его экземпляр в BackgroundWorker.Событие DoWork.Оттуда вы можете вызвать свой метод для загрузки файла:

Private Sub bgwMain_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwMain.DoWork
    m_oJobEngine = New JobEngine(CType(sender, BackgroundWorker))
    m_oJobEngine.DownloadFile(CStr(e.Argument))
End Sub

Чтобы сообщать пользователю о ходе выполнения, вы можете обрабатывать события, вызванные вашим классом, в вашей основной форме.Вам просто нужно убедиться, что объявление объекта класса job содержит ключевое слово WithEvents.Из этих обработчиков вы можете вызвать метод ReportProgress BackgroundWorker.Из ReportProgress вы можете вносить любые необходимые изменения в пользовательский интерфейс, чтобы указывать на прогресс.Вот пример:

Private Sub m_oJobEngine.DownloadProgress(ByVal bgw as Backgroundworker, ByVal bytesTransferred as Long) Handles m_oJobEngine.DownloadProgress
    bgw.ReportProgress(0, bytesTransferred)
End Sub
Private Sub bgwMain_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgwMain.ProgressChanged
    lblStatus.Text = CLng(e.UserState).ToString & " bytes transferred."
End Sub

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

Другие советы

Если вы собираетесь только выполнять загрузку и вам не нужна другая асинхронная обработка, вы можете просто использовать асинхронные методы WebClient класс.Хотя, поскольку у вас уже есть свой собственный класс, это, вероятно, не решение для вас.

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

Редактировать: Короткая история такова:

  • Вы создаете BackgroundWorker от звонящего;
  • Когда вы хотите начать фоновую работу, вы вызываете BackgroundWorker.RunWorkerAsync;
  • в DoWork обработчик событий вы выполняете фоновую работу, в вашем случае вы запускаете свой класс загрузки;
  • пока вы выполняете фоновую работу, вам нужно время от времени проверять наличие CancelationPending;
  • когда вы хотите сообщить о каком-либо прогрессе, вам нужно вычислить его в процентах и вызвать ReportProgress.

И если вам нужно что-то действительно индивидуальное, вы всегда можете создать свое собственное Thread.

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

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

Я бы настоятельно посоветовал BackgroundWorker если вам нужно предоставить пользователю обратную связь по пользовательскому интерфейсу.В ProgressChanged и RunWorkerCompleted события выполняются в потоке пользовательского интерфейса, поэтому нет необходимости выполнять сортировку, которая может усложнить ваш код.

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

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

Или вы могли бы сделать что-то вроде:

WaitCallBack workCallBack= new WaitCallBack(DownloadMethod);
if(!ThreadPool.QueueUserWorkItem(workCallBack, "ThreadPooled")
{
   // Unable to Pool
}

// Work has been added to pool and will execute when possible

Зависит от того, какие параметры, если таковые имеются, вам нужны для потока.

Класс, который использует clsDownload (вероятно, ваш класс Form), должен использовать BackgroundWorker для запуска метода загрузки.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top