Hallo,
folgendes Problem:
Ich habe eine Form mit einem StatusStrip, auf dem ein TollStripStatusLabel und eine TollStripProgressBar sind.
Die ProgressBar ist folgendermaßen voreingestellt:
this.toolStripProgressBar.Name = "toolStripProgressBar";
this.toolStripProgressBar.Size = new System.Drawing.Size(40, 16);
this.toolStripProgressBar.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
this.toolStripProgressBar.Visible = false;
(Maximum steht auf 100 / Minimum auf 0 ...)
Die ProgressBar soll nur bei Bedarf aufgerufen werden.
Um dies zu realisieren habe ich eine Methode geschrieben die je nach Bedarf einen invoke durchführt oder aber direkt mit der ProgressBar "spricht"
public void SetProgressBar(Boolean xx_aktiv = false)
{
try
{
if (this.statusStrip1.InvokeRequired)
{
this.statusStrip1.Invoke(new MethodInvoker(() => this.toolStripProgressBar.Visible = xx_aktiv));
this.statusStrip1.Invoke(new MethodInvoker(() => this.statusStrip1.Refresh()));
}
else
{
this.toolStripProgressBar.Visible = xx_aktiv;
this.statusStrip1.Refresh();
}
}
catch (Exception ex) { }
}
Nun zu meinem Problem:
die ProgressBar wird nicht sichtbar 🤔 - egal, ob ich das direkt oder in einem BgWorker mache.
Wenn ich durch steppe, so sehe ich das die Eigenschaft zwar auf Visible = true gesetzt wurde, aber es passiert nichts ...
Wenn ich aber die Eigenschaft Visible in den Form-Eigenschaften auf true stelle, dann sehe ich die ProgressBar, sobald die Maske angezeigt wird (was ich ja nicht will...).
Kann mir das bitte mal jemand plausibel erklären ?
MfG ChrisProg
Ich würde fast wetten er läuft in den catch und Du bemerkst es nicht, weil das try/catch so einfach sinnlos und quatsch ist 😉
Mach es wie [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) es vorsieht.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo Abt,
das ist es nicht, denn wie ich schrieb "Wenn ich durch steppe, so sehe ich das die Eigenschaft zwar auf Visible = true gesetzt wurde, aber es passiert nichts ..." - er geht nicht in eine Exception...
"weil das try/catch so einfach sinnlos und quatsch ist" - meinst Du das generell, oder für diesen Fall ?
Wenn generell, bitte erklären ...
(wenn in diesem Fall, hast Du wohl recht, das ist noch übrig geblieben vom Start-Code - aber schaden tuts ja auch nicht, oder?)
MfG ChrisProg
Hallo,
du fängst die Exception, behandelst sie aber nicht.
glandorf
Das ist mir schon klar u. soll auch so sein...
Es geht hier ja "nur" um eine Anzeige für den User (also nichts wichtiges) - wenn es, warum auch immer, hier zu einem Fehler kommen sollte, dann soll dadurch nicht das Programm behindert werden ...
MfG ChrisProg
Die Leute meinen du sollst die Exception richtig behandeln damit du erfährst was der Fehler ist. Mach da wenigstens ein Breakpoint ran.
Nochmal: das ist nicht mein Problem ! er geht in keine Exception !!!
Im Anhang des Screenshots im Debug-Modus (vor dem setzen):
(eingefühte IMGs werden leider nicht akzeptiert...)
er führt die Befehle aus, die Progressbar wird aber trotzdem nicht sichtbar ...
Was ich aber vergessen habe zu erwähnen:
Der StatusStrip sitzt auf einer vererbten Form, auch der hier gezeigte Quellcode ist in der vererbten Form, der Aufruf erfolgt in der "Unterform" mit
SetProgressBar(true);
Was aber meiner Meinung nach kein Problem darstellen sollte, oder ?
Es funktionert nur, wenn ich die ProgressBar in der Entwicklungsumgebung auf Visible = true setzte !
Dann muss ich es aber im im Form-Aufruf nach InitializeComponent() wieder auf
toolStripProgressBar.Visible = false;
setzen, was ich aber eigentlich nicht will (--> mögliches "flackern"...)
MfG ChrisProg
hier der nächste Schreenshot nach dem Steps ...
Ich tippe auf [FAQ] Warum blockiert mein GUI?
Wieso wird hier überhaupt Invoke
aufgerufen, d.h. rufst du SetProgressBar(true)
aus einem anderen Thread heraus aus?
Das war auch zuerst meine Vermutung, deshalb habe ich mir den Artikel durchgelesen - aber: die Aktionen sind keinesfalls "langlaufend".
Dagegen spricht auch, das alles funktioniert, wenn man die ProgressBar beim Initialize schon auf Visible = true hat (und dann direkt wieder auf Visible = false setzt) ...
Und ja, da die eigentliche Codeausführung (Upload von Dateien) länger dauern kann, wird das ganze aus einem BgWorker heraus (gleich zu Beginn) aufgerufen ...
Die ProgressBar soll dabei den Fortschritt anzeigen.
MfG ChrisPorg
Und die Form ist auch aktiv und bedienbar?
Oder blockierst du in einem der Form
-Ereignisse den weiteren Ablauf?
PS: Beim BackgroundWorker
gibt es das ProgressChanged-Ereignis (das im UI-Thread läuft, so daß kein eigenes Invoke
mehr nötig ist).
Außerdem kann man die gesamte Funktionalität besser mit asynchroner Programmierung umsetzen.
Mach es ordentlich mit async/await, wie in dem bereits geposteten Link.
Wenn Du es so nicht machen willst, dann musst halt mit Fehlern leben 🤔
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Th69:
Ich hab mal ein System.Threading.Thread.Sleep(15000); eingebaut um das zu testen - Ja, die Form ist aktiv (lässt sich verschieben) und bedienbar (Klick auf Abbrechen-Button wird ausgeführt) ...
Das mit ProgressChanged kann hier doch noch gar nicht greifen, ich will doch erst einmal die ProgressBar sichtbar machen...
"Außerdem kann man die gesamte Funktionalität besser mit asynchroner Programmierung umsetzen." - dabei könnte ich aber dem User nicht zeigen, wie weit die Datei ist (außer ich würde für jede Datei eine ProgressBar erstellen) ...
Und, ich sehe im massenhaften parallelen Upload ein Performance-Problem (alleine schon durch die Bandbreite ...)
@Abt:
Es liegt nicht am BGWorker - wenn ich
SetProgressBar(true);
aus der Form direkt aufrufe, dann durchläuft er die "else"-Schleife , steht wieder die Eigenschaft richtig, aber es wird nicht angezeigt ...
Ich werde halt damit leben müssen, das ich die ProgressBar in der Entwicklung auf visible=true und dann direkt beim Aufruf wieder auf visible = false setzten muß - nur verstehen tue ich das nicht ...
MfG ChrisProg
Ja, das Verhalten ist auch korrekt.
Wenn Dich das wundert, wenn fehlen Dir hier einfach die Basics von Forms und Co.
Aber gut; die Leute versuchen Dir hier zu helfen und Du magst Dich mit Händen und Füßen wehren.
Da kann man halt nichts machen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
@Abt:
ich bin weiß Gott nicht allwissend und weit davon entfernt perfekt zu sein, aber die Antwort finde ich doch etwas herablassend ...
Wenn Du es weißt, wäre es dann nicht besser, andere an deinem Wissen teil haben zu lassen ?
Mittlerweile weiß ich, was passiert (Bug?):
der StatusStrip steht auf AllowMerge = true, in ihm sind zwei Objekte enthalten:
Wenn ich nun die Form starte und die Größe(Breite) ändere, dann passt sich der StatusStripText entsprechend an (wie erwartet).
Gem Microsoft Docs bedeutet Spring:
Eigenschaftswert
Boolean
true, wenn ToolStripStatusLabel beim Ändern der Größe des Formulars automatisch den verfügbaren Leerraum von StatusStrip füllt; andernfalls false. Der Standardwert lautet false.
Nach meinem Verständnis würde das bedeuten, das wenn ein anderes Objekt hinzukommt, der verfügbare Leerraum kleiner wird u. dementsprechend auch der StatusStripText kleiner werden müsste - dem ist aber nicht so !
Wenn man nun, nachdem man die ProgressBar programmatisch auf Visible = true gesetzt hat, die Form langsam (so das der Rechner das noch zeichnen kann) in der Breite verändert, passiert immer noch nichts - wenn man das aber ruckartig macht, erscheint plötzlich die ProgressBar ...
Die Eigenschaft AutoSize des StatusStripTextes ist der entscheindende Wert - ich hatte ihn auf false gestellt, da ich glaubte, das das zusammen mit Spring nicht sauber funktionieren würde (doppelt gemoppelt)...
Aber: wenn ich AutoSize auf true stelle, dann funktioniert es sofort - ist für mich nicht wirklich nachvollziehbar, aber es ist so ...
Du siehst: es hatte wirklich nichts mit Threading zu tun ...
Ich wehre mich bestimmt nicht gegen Hilfe und bin dafür auch dankbar (so bin ich auch dankbar für den Hinweis auf asynchrone Programmierung, die bisher noch nicht auf meinem Radar war (in VFP gänzlich unbekannt...) - aber ich werde mich da mal einlesen...)
MfG ChrisProg
Immer schwierig vernünftig zu reden, wenn man Kritik immer als herablassend aufnimmt.
Aber gut; so ist die Gesellschaft halt...
Wenn Du es weißt, wäre es dann nicht besser, andere an deinem Wissen teil haben zu lassen ?
Mehrfach wurdest Du nun auf asynchroner Programmierung hingewiesen; dass das der bessere Weg ist.
Direkt und über den Hinweis auf die Artikel in der FAQ, die selbiges (mit Grund) aussagen.
Wenn Du also immer noch nach "Wissen" fragst, dann zeigt mir das zwei Dinge:
Beide Fälle sind halt nicht zielführend und Grundlage meiner Aussage.
Ein Minimalstbeispiel (respektive [Tutorial] Vertrackte Fehler durch Vergleich von echtem Projekt mit minimalem Testprojekt finden ) kann so aussehen, funktioniert einwandfrei.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
toolStripProgressBar1.Visible = false;
}
private async void button1_Click(object sender, EventArgs e)
{
await RunStatus();
}
public async Task RunStatus()
{
toolStripProgressBar1.Visible = true;
toolStripProgressBar1.Value = 0;
while (toolStripProgressBar1.Value < 100)
{
toolStripProgressBar1.Value += 1;
await Task.Delay(100);
}
toolStripProgressBar1.Visible = false;
}
}
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Hallo @Abt,
Danke !
Nur zum Verständnis:
Wenn ich deinem Bespiel folge, dann kann (sollte) ich ja im Prinzip alles was ich Auslöse mit async / await machen, oder würdest Du das auch machen, wenn tatsächlich "nur" visible gesetzt würde und das "füllen" an anderer Stelle passiert (und dann das "füllen" mit async /await machen)?
Macht dieses Vorgehen dann den BgWorker nicht gänzlich überflüssig?
Zu meinem tatsächlichen Problem:
Ist das denn für Dich nachvollziehbar, das ich zusätzlich zum Spring auch das Autosize auf true gesetzt haben muss, oder ist das tatsächlich ein Bug?
P.S.: kann man hier irgendwie einen Beitrag als gelöst / erledigt markieren ?
MfG ChrisProg
alles was ich Auslöse mit async / await machen,
Verwende async/await wo sinnvoll, nicht überall.
Macht dieses Vorgehen dann den BgWorker nicht gänzlich überflüssig?
Wow. Richtig!
Aber: wenn Du den verlinkten Artikel gelesen hättest, dann hättest Du bereits gelesen, dass der BGW in die Mottenkiste gehört und fast alles mit async/await gelöst werden kann.
Ebenso hat das Th69 bereits inhaltlich ausgedrückt => asynchrone Programmierung.
Das ist genau das was ich meine....
P.S.: kann man hier irgendwie einen Beitrag als gelöst / erledigt markieren ?
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code