Question

Je souhaite commencer un travail dans un nouveau fil de discussion ou utiliser un arrière-plan pour le faire, mais je ne l’ai pas fait auparavant et je vous demande de quelle manière je devrais le faire.

Mon programme a un datagridview avec une liste de fichiers, un fichier par ligne. Je souhaite que l'utilisateur puisse sélectionner une ligne, puis appuyer sur " Démarrer le téléchargement " pour démarrer un travail en arrière-plan du téléchargement. Je souhaite obtenir des informations sur l'avancement du téléchargement.

J'ai une classe clsDownload qui gère tout et déclenche des événements mais comment puis-je implémenter le backgroundworking?

Dois-je utiliser System.ComponentModel.BackgroundWorker à l'intérieur de la classe ou créer un wrapper qui gère cela ou utiliser un autre type de thread??

Merci.

Modifier: Je ne comprends pas comment implémenter mon téléchargement dans le backgroundworker, un petit exemple serait très agréable. L'exemple sur msdn ne m'a pas conduit loin.

J'ai une classe de téléchargement qui a une fonction StartDownload. Devrais-je utiliser le backgroundworker DANS la classe ou dans l'appelant? "se sentir stupide"

Était-ce utile?

La solution

J'ai créé plusieurs classes différentes intégrant BackgroundWorker. Ce que je fais généralement, c’est que le formulaire BackgroundWorker comporte un composant qui sera ouvert lorsque le travail est en cours d’exécution, puis je passe cette instance au constructeur de ma classe de travaux.

Voici à quoi pourrait ressembler votre classe d'emplois:

Private m_bwMain As BackgroundWorker

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

    'additional setup code here
End Sub

Pour commencer un travail, vous feriez quelque chose comme ceci dans le gestionnaire d'événements Click de votre bouton Démarrer le téléchargement:

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

Je déclare ma classe d'emplois en tant que membre privé du formulaire actuel, puis je l'instancie dans l'événement BackgroundWorker.DoWork. À partir de là, vous pouvez appeler votre méthode pour télécharger un fichier:

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

Pour signaler la progression à l'utilisateur, vous pouvez gérer les événements soulevés par votre classe dans votre formulaire principal. Vous devez simplement vous assurer que la déclaration d'objet de classe de travail contient le mot clé WithEvents. À partir de ces gestionnaires, vous pouvez appeler la méthode ReportProgress de BackgroundWorker. Dans ReportProgress, vous pouvez apporter toutes les modifications nécessaires à l'interface utilisateur pour indiquer la progression. Voici un exemple:

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

J'espère que cela vous aidera.

Autres conseils

Si vous ne faites que télécharger et que vous n'avez pas besoin d'un autre traitement async, vous pouvez simplement utiliser les méthodes asynchrones du WebClient . Bien que puisque vous avez déjà votre propre classe, ce n'est probablement pas une solution pour vous.

Sinon, vous pouvez utiliser BackgroundWorker comme vous l'avez mentionné. La page MSDN propose un exemple d'utilisation.

EDIT: La nouvelle est la suivante:

  • Vous créez le BackgroundWorker à partir de l'appelant;
  • Lorsque vous souhaitez démarrer le travail en arrière-plan, appelez BackgroundWorker.RunWorkerAsync ;
  • .
  • dans le gestionnaire d'événements DoWork , vous effectuez le travail en arrière-plan, dans votre cas, vous démarrez votre classe de téléchargement;
  • pendant que vous travaillez en arrière-plan, vous devez vérifier de temps en temps que CancelationPending ;
  • lorsque vous souhaitez signaler des progrès, vous devez le calculer en pourcentage et appeler ReportProgress .

Et si vous avez besoin de quelque chose de vraiment personnalisé, vous pouvez toujours créer votre propre Fil de discussion .

Personnellement, je resterais avec BackgroundWorker . Il a un bel ensemble de notifications pour les différentes étapes du travail. Si vous utilisez Thread , vous devrez les implémenter vous-même.

Je voudrais également m'assurer que le code ne crée pas trop d'instances. Vous souhaitez limiter le nombre de téléchargements simultanés et mettre en file d'attente tout dépassement de ce nombre.

Je conseillerais vivement à BackgroundWorker si vous devez fournir des commentaires à l'utilisateur sur l'interface utilisateur. Les événements ProgressChanged et RunWorkerCompleted sont exécutés sur le thread d'interface utilisateur; vous n'avez donc pas besoin de faire du marshalling, ce qui peut rendre votre code plus complexe.

L'agent d'arrière-plan semble fonctionner normalement ... Il existe un exemple sur MSDN.

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

Ou vous pourriez faire quelque chose comme:

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

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

Dépend quels paramètres, le cas échéant, vous avez besoin pour le thread.

La classe qui utilise clsDownload (probablement votre classe Form) doit utiliser BackgroundWorker pour exécuter la méthode de téléchargement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top