Ich möchte den Fortschritt von Berechnungen zeigen, die in einer externen Bibliothek ausgeführt werden.
Wenn ich beispielsweise eine Berechnungsmethode habe und diese für 100000 Werte in meiner Formularklasse verwenden möchte, kann ich Folgendes schreiben:
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();
}
}
}
Ich sollte nach jeder Berechnung einen Schritt ausführen. Was aber, wenn ich alle 100000 Berechnungen in einer externen Methode durchführe? Wann sollte ich "Schritt ausführen", wenn ich diese Methode nicht vom Fortschrittsbalken abhängig machen möchte? Ich kann zum Beispiel schreiben
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);
}
}
aber so will ich das nicht machen.
c#
winforms
progress-bar
Dmytro
quelle
quelle
Antworten:
Ich würde vorschlagen, dass Sie sich BackgroundWorker ansehen . Wenn Sie eine so große Schleife in Ihrem WinForm haben, wird diese blockiert und Ihre App sieht aus, als wäre sie hängen geblieben.
Sehen Sie sich an
BackgroundWorker.ReportProgress()
, wie Sie den Fortschritt an den UI-Thread zurückmelden können.Beispielsweise:
quelle
BackgroundWorker
über den Designer hinzugefügt und dort konfiguriert wird. Aber ja, es muss so konfiguriert werden, dass esWorkerReportsProgress
eingestellt isttrue
.RunWorkerCompleted
Event-Handler, wenn IhrDoWork
Handler es nicht tut ..Seit .NET 4.5 können Sie eine Kombination aus Async verwenden und mit Progress auf das Senden von Updates an den UI-Thread warten :
Aufgaben sind derzeit die bevorzugte Methode, um zu implementieren, was
BackgroundWorker
funktioniert.quelle
await DoWorkAsync(progress);
? Dies ist sehr absichtlich, da dies nicht dazu führen würde, dass ein zusätzlicher Thread ausgeführt wird. Nur wennDoWorkAsync
esawait
zum Beispiel auf eine E / A-Operation warten würde, würde diebutton1_Click
Funktion fortgesetzt. Der Haupt-UI-Thread ist für diese Dauer blockiert. WennDoWorkAsync
es nicht wirklich asynchron ist, sondern nur viele synchrone Anweisungen, erhalten Sie nichts.Step
es nur in der Fortschrittsanzeige von WinForms verfügbar ist und hier nicht benötigt wird, aber es war im Beispielcode der Frage (getaggte Winforms) vorhanden, also könnte es bleiben.Hey, es gibt ein nützliches Tutorial zu Dot Net-Perlen: http://www.dotnetperls.com/progressbar
In Übereinstimmung mit Peter müssen Sie eine gewisse Menge an Threading verwenden, da das Programm sonst nur hängen bleibt und den Zweck etwas zunichte macht.
Beispiel mit ProgressBar und BackgroundWorker: C #
quelle
Es
Task
gibt, es ist Unnesscery mitBackgroundWorker
,Task
ist einfacher. beispielsweise:ProgressDialog.cs:
Getan! Dann können Sie ProgressDialog überall wiederverwenden:
quelle