2010-11-15 4 views
2

Un peu nouveau en C# mais j'ai un gros problème pour faire fonctionner ces choses car si mon background worker exécute un long processus en utilisant une méthode d'une autre classe, alors cette classe n'a pas accès au background worker le progrès.Comment puis-je mettre à jour une barre de progression de l'interface utilisateur ou un arrière-plan du code dans une classe distincte?

Par exemple:

private void bgWorker_DoWork(object sender DoWorkEventArgs e) 
{ 
    bgArgs args = e.Argument as bgArgs; 
    MyClass objMyClass = new MyClass(); 

    MyClass.MyMethod(strValue, args.Option); 

    //Do something based on return value of long process. 
} 

Si je tente de mettre à jour bgWorker de la « MyClass » de classe, il ne peut pas « voir » bgWorker, il n'existe pas dans le contexte de la classe, il est dans l'interface utilisateur classe car dans Visual Studio, c'est là que vous le faites glisser depuis la boîte à outils. La seule façon de l'utiliser est de passer la totalité de l'interface utilisateur à la classe, ce qui crée d'autres problèmes lorsque j'essaie d'accéder à cette classe à partir de n'importe où, à l'exception du formulaire principal. De là, je viens de mettre à jour la barre de progression manuellement via ProgressBar1.PerformStep() car il traverse les boucles.

De plus, j'ai déjà changé le modificateur de ma barre de progression en interne, donc ce n'est pas que la classe ne voit pas la barre de progression.

Je pourrais être en mesure de passer le bgworker par lui-même à la classe grâce à la méthode, mais cela ne semble pas juste.

Répondre

1

Je pense que votre architecture doit être révisée ici. L'arrière-plan est pour exécuter des opérations en arrière-plan, comme hors de vue-hors-de-esprit. Pendant qu'il est en cours d'exécution, vous pouvez en accepter les commentaires en observant l'événement BackgroundWorker.ProgressChanged, qui vous aidera à incrémenter votre barre de progression avec PerformStep(). Cependant, vous ne devez pas essayer de modifier BackgroundWorker pendant son exécution. Cela vous amène à Threading problèmes, dont je ne suis pas sûr que vous voulez vraiment :) Vous voyez, BackgroundWorker utilise un thread différent pour effectuer ses opérations quand il s'exécute, donc le changer en cours d'exécution signifie que vous devez accéder au thread qu'il exécute son travail sur. Cela devient laid. Il est préférable de lui donner une méthode à exécuter, de l'exécuter, de vérifier son ProgressChanged et d'attendre qu'elle se termine.

+0

Comment vérifier la progression de la modification? Par exemple, la méthode parcourt un nombre variable de sessions sur une batterie de serveurs Citrix pour rechercher un utilisateur spécifique. Comme il commence, je l'ai mis la barre au maximum au nombre total de sessions, puis commencer la boucle, comme il boucle à travers elle étapes de la barre de progression d'un. C'est très précis, mais comment le bgworker savoir jusqu'où le progrès est? –

1

En supposant que je comprends correctement votre question, vous devrez probablement créer une méthode qui peut accéder à la barre d'avancement de l'interface utilisateur malgré le thread source. Le ci-dessous fera juste cela vous épargner de faire exploser l'application lorsque vous essayez de définir la valeur.

private delegate void UpdateProgressBarCallback(int barValue); 
private void UpdateProgressBarHandler(int barValue) 
{ 
    if (this.progressBar1.InvokeRequired) 
     this.BeginInvoke(new UpdateProgressBarCallback(this.UpdateProgressBarHandler), new object[]{ barValue }); 
    else 
    { 
     // change your bar 
     this.progressBar1.Value = barValue; 
    } 
} 

[voir http://msdn.microsoft.com/en-us/library/ms171728%28VS.80%29.aspx]

Ensuite, vous appelez simplement UpdateProgressBar (valeur); (De même, si vous voulez que cela marche, vous pouvez ajuster les arguments/la façon dont la méthode fonctionne)

Ensuite, vous pouvez procéder de différentes façons: Vous pouvez transformer votre arrière-plan (puisque c'est déjà dans une autre classe) puis joignez les changements de progression et mettez à jour l'interface utilisateur; ou vous pouvez passer un délégué aux threads comme référence afin qu'il sache où ajuster l'interface utilisateur. Commentez et laissez-moi une direction pour aller et je verrai si je peux vous aider (et confirmez que je comprends la question).

+0

Lorsque vous utilisez ce modèle, utilisez [BeginInvoke] (http://msdn.microsoft.com/en-us/library/a06c0dc2.aspx) au lieu de Invoke.La classe Control a une exception à la BeginXxxx a besoin d'une règle EndXxxx (voir la section remarques de l'article MSDN que j'ai lié). Cela fera que l'appel de début ne bloquera pas et ne tiendra pas votre deuxième fil. –

+0

Touché. C'est ce que je reçois pour le dactylographier ad-hoc. Mais merci pour la référence, je mettrai à jour le code dans mon post. –

+0

Ce n'est pas que je ne peux pas accéder à la barre de progression à partir d'un thread séparé, c'est que je ne peux pas accéder au travailleur d'arrière-plan à partir d'une classe distincte. La méthode de classe est ce qui fait tout le travail. Une fois que l'agent d'arrière-plan a transmis le travail à cette méthode, la méthode n'a aucune idée d'où elle vient et ne peut donc pas faire de bgWorker.ReportProgress(). –

Questions connexes