Je veux montrer la progression des calculs, qui sont exécutés dans une bibliothèque externe.
Par exemple, si j'ai une méthode de calcul et que je veux l'utiliser pour 100000 valeurs dans ma classe Form, je peux écrire:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Caluculate(int i)
{
double pow = Math.Pow(i, i);
}
private void button1_Click(object sender, EventArgs e)
{
progressBar1.Maximum = 100000;
progressBar1.Step = 1;
for(int j = 0; j < 100000; j++)
{
Caluculate(j);
progressBar1.PerformStep();
}
}
}
Je devrais effectuer une étape après chaque calcul. Mais que faire si j'effectue tous les 100000 calculs en méthode externe. Quand dois-je "exécuter l'étape" si je ne veux pas que cette méthode dépende de la barre de progression? Je peux, par exemple, écrire
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void CaluculateAll(System.Windows.Forms.ProgressBar progressBar)
{
progressBar.Maximum = 100000;
progressBar.Step = 1;
for(int j = 0; j < 100000; j++)
{
double pow = Math.Pow(j, j); //Calculation
progressBar.PerformStep();
}
}
private void button1_Click(object sender, EventArgs e)
{
CaluculateAll(progressBar1);
}
}
mais je ne veux pas faire comme ça.
c#
winforms
progress-bar
Dmytro
la source
la source
Réponses:
Je vous suggère de jeter un œil à BackgroundWorker . Si vous avez une boucle aussi grande dans votre WinForm, elle se bloquera et votre application aura l'air de se bloquer.
Regardez
BackgroundWorker.ReportProgress()
pour voir comment rendre compte de la progression vers le fil de discussion de l'interface utilisateur.Par exemple:
la source
BackgroundWorker
est ajouté via le concepteur et configuré ici. Mais oui, il devra être configuré pour êtreWorkerReportsProgress
défini surtrue
.RunWorkerCompleted
gestionnaire d'événements, si votreDoWork
gestionnaire ne le fait pas ..Depuis .NET 4.5, vous pouvez utiliser une combinaison d' async et attendre avec Progress pour l'envoi de mises à jour au thread d'interface utilisateur:
Les tâches sont actuellement le moyen préféré de mettre en œuvre ce que
BackgroundWorker
fait.la source
await DoWorkAsync(progress);
? C'est tout à fait exprès, car cela n'entraînerait pas un thread supplémentaire en cours d'exécution. Ce n'est que si laDoWorkAsync
fonction s'appellerait elle-mêmeawait
pour, par exemple, attendre une opération d'E / S, que labutton1_Click
fonction continuerait. Le thread d'interface utilisateur principal est bloqué pendant cette durée. Si ceDoWorkAsync
n'est pas vraiment asynchrone mais juste beaucoup d'instructions synchrones, vous ne gagnez rien.Step
n'est disponible que dans la barre de progression de WinForms et n'est pas nécessaire ici, mais Il était présent dans l'exemple de code de la question (winforms étiqueté), donc peut-être qu'il pourrait rester.Hé, il y a un tutoriel utile sur les perles Dot Net: http://www.dotnetperls.com/progressbar
En accord avec Peter, vous devez utiliser une certaine quantité de threading ou le programme se bloque, ce qui va quelque peu à l'encontre de l'objectif.
Exemple qui utilise ProgressBar et BackgroundWorker: C #
la source
Il
Task
existe, c'est unnesscery en utilisantBackgroundWorker
,Task
c'est plus simple. par exemple:ProgressDialog.cs:
Terminé! Ensuite, vous pouvez réutiliser ProgressDialog n'importe où:
la source