J'ai récemment travaillé sur une application où je voulais afficher la progression d'un autre thread dans la barre d'état via le contrôle ToolStripProgressBar
contenu dans le champ StatusBar
. Avant que j'aie essayé d'ajouter ce code j'ai d'abord eu le code changeant le texte d'un contrôle ToolStripStatusLabel
et pour ce faire j'ai utilisé la méthode Invoke avec des délégués et tout a bien fonctionné. Cependant, j'ai trouvé que quand j'ai essayé ceci avec le ToolStripProgressBar
l'appel à la méthode Invoke
de la barre d'état a échoué sans notification (aucune erreur, aucune exception, rien). Ce que j'ai appris depuis, c'est que pour utiliser une barre de progression de cette façon, j'ai dû utiliser un contrôle BackgroundWorker
. Donc, mon code fonctionne, mais je ne comprends pas pourquoi je ne pouvais pas utiliser la méthode Invoke
qui semblait déjà fonctionner.Pourquoi la méthode StatusBar.Invoke ne fonctionne pas pour un ToolStripProgressBar?
Quelques exemples de ce qui a fonctionné et ce qui n'a pas:
Cela a fonctionné
public delegate void changeStatusMessage(String message);
public changeStatusMessage changeStatusMessageDelegate;
public void changeStatusMessageMethod(String message){
if(statusbar.InvokeRequired){
statusbar.Invoke(changeStatusMessageDelegate, new Object[] {message});
}else{
toolstripLabel.Text = message;
}
}
Cela ne fonctionne pas
public delegate void incrementProgressBar(int value);
public incrementProgressBar incrementProgressBarDelegate;
public void incrementProgressBarMethod(int value){
if(statusbar.InvokeRequired){
statusbar.Invoke(incrementProgressBarDelegate, new Object[] {value});
}else{
toolstripProgress.Increment(value);
}
}
Dans l'exemple qui ne fonctionnait pas la propriété InvokeRequired
est vrai, donc la méthode Invoke
est appelée et rien ne se passe. Où, comme je m'y attendais, j'appelle à nouveau le incrementProgressBarMethod
cette fois où InvokeRequired
est faux et permettant ainsi à la méthode Increment
de se déclencher.
Je voudrais vraiment savoir pourquoi cela ne fonctionne pas. Comme je l'ai dit, j'ai déjà rééquipé pour utiliser un BackgroundWorker
, je veux juste une explication.
Il n'y a rien d'un TSPB spécial qui vous remettra une explication facile. Control.Invoke() tend à se bloquer facilement si le thread principal est bloqué, donc "rien ne se passe" n'est pas rare. Stick avec BackgroundWorker. –
Je n'ai jamais dit que je voulais une explication "Facile", les plus compliqués fonctionneraient aussi bien. Me dire simplement que Control.Invoke() peut causer une impasse ne me suffit pas vraiment pour comprendre la raison. Le Control.Invoke() est fourni pour une raison, pourquoi je ne peux pas l'utiliser pour ce contrôle unique, quand un contrôle géré de la même manière avec le même code fonctionne sans problème. – JRSofty
Post code repro qui démontre le problème et n'importe qui peut tester et vous obtiendrez votre réponse. –