Autor Beitrag
schnips
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Do 10.05.12 15:24 
Hallo zusammen.

Ich habe in einem Konsolenprojekt eine Downloadfunktion geschrieben die mir mit Hilfe des Backgroundworkers den aktuellen Fortschritt anzeigt. Dies funktioniert auch einwandfrei.
Da ich in einem anderen Projekt(Windowsforms) die gleiche Funktion benötige, habe ich diese dort eingebaut. Das Problem ist dass meine Form einfriert sobald der Backgroundworker arbeitet, was ja eigentlich der Backgroundworker verhindern sollte bzw deshalb benutze ich ihn ja. Ich habe dann einiges von meinem Code auskommentiert, sodass im Backgroundworker "nur noch" eine lang andauernde Schleife statt findet. Dann funktioniert es und meine Form friert mir nicht ein. Wenn ich aber meinen Methodenaufruf des Downloads an die Stelle der Schleife setze, friert meine Form wieder ein...
Naja, Code ist ja fast schon selbserklärend aber trotzdem, so bin ich vorgegangen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
btnClick(...)
{
    Worker.RunWorkerAsync();
}

Worker_DoWork(...)
{
    //Hier die Schleife bzw. Downloadmethode
}


Es zeigt ja irgendwie alles darauf dass es an der Downloadmethode liegt. Gibt es irgendwelche Vorschriften von Methodenaufrufe innerhalb von Worker_DoWork? Darf die Methode von einer anderen Klasse stammen? Und achja, wieso funktioniert mein Code in einem Konsolen-Projekt aber nicht in einem WinForms-Projekt?
Ich komm einfach nicht weiter und bin somit für jede Hilfe dankbar!

Gruß schnips

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 10.05.12 16:02 
Hallo schnips :welcome:

bitte zeige mal den (relevanten) Teil der DoWork-Methode?
Du darfst nicht direkt in dieser Methode auf GUI-Elemente zugreifen, sondern mußt dafür dann entweder das BackgroundWorker.ProgressChanged-Ereignis benutzen oder aber die Invoke-Methode aufrufen (s. z.B. myCSharp.de - [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)).

Gerade für die Fortschrittsanzeige wurde extra das BackgroundWorker.ProgressChanged-Ereignis entworfen - dazu mußt du dann zuerst die Eigenschaft BackgroundWorker.WorkerReportsProgress aktivieren und dann in der DoWork-Methode die ReportProgress(prozentwert)-Methode aufrufen.
Und in dem oben genannten Ereignis kannst du dann einfach eine ProgressBar (oder jedes andere GUI-Element) aktualisieren (ohne Invoke dafür extra aufrufen zu müssen).

P.S. Und in dem Konsolenprojekt hast du ja (wahrscheinlich) nur Console.Write aufgerufen, welches direkt synchron ausgeführt wird (WinForms dagegen arbeitet intern mit einem Nachrichtenpuffer (MessageQueue) und arbeitet diese dann im GUI-Thread der Reihe nach ab - sofern die GUI eben nicht blockiert - auch dazu gibt es einen FAQ-Eintrag myCSharp.de - [FAQ] Warum blockiert mein GUI?).
schnips Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 11.05.12 09:30 
Morgen Th69,

vielen Dank für deine schnelle Antwort.

Zur Kommunikation habe ich eine USB-Interface-Lib eingebunden welche nicht von mir stammt. Daher kann ich dir lediglich den Methodenaufruf beschreiben, wenn es was bringt!?

int Download(int iParameter1, int iParameter2, string strHexPfad);

Es finden keine Progress-Changes-Events statt, habe alles auskommentiert. Wollte erst mal erreichen dass mein Download im Hintergrund statt findet und meine GUI nicht einfriert...
Habe mal gelesen dass man bei einem Methodenaufruf innerhalb des Backgroundworkers darauf achten muss welche Parameter benutzt werden, also man soll keine Parameter eines anderen Threads benutzen. Das habe ich aber auch ausgeschlossen in dem ich keine Parameter sondern einfach nur Werte benutzt habe. Wahrscheinlich liegt es an dem Downloadbefehl und ich sollte mich mal mit dem Entwickler der USB-Interface-Lib kurzschließen, oder?
Weiß echt nicht mehr weiter...

Gruß schnips

_________________
There are two rules for success.
1. Never tell everything you know. -Roger H. Lincoln-
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 11.05.12 09:39 
Hallo,

dann scheint es wohl wirklich ein Problem mit der Library (in Verbindung mit WinForms) zu geben.
Dann wende dich mal an dessen Entwickler.

Viel Erfolg.
schnips Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 11.05.12 09:53 
Ok, werde ich machen.
Vielen dank.

Melde mich wieder wenn das Problem gelöst wurde.

Gruß
schnips

_________________
There are two rules for success.
1. Never tell everything you know. -Roger H. Lincoln-
schnips Threadstarter
Hält's aus hier
Beiträge: 4



BeitragVerfasst: Fr 11.05.12 14:02 
Hallo Th69,

Problem gelöst.
Es lag daran dass mein Objekt der USB-Interface-Lib im GUI-Thread instanziert wurde. Durch den Aufruf der Downloadmethode im Backgroundworker-Thread startet mein USB-Interface Objekt den Download in dem Thread in dem er instanziert wurde. Das Objekt muss also im Backgroundworker-Thread instanziert werden.

Puh, schwere Geburt. Nach drei Tagen endlich geschafft! :)

Grüße schnips

_________________
There are two rules for success.
1. Never tell everything you know. -Roger H. Lincoln-