Laden...

Fehlerhaftes Zeichnen des GUI trotz BGW

Erstellt von RattuS vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.134 Views
RattuS Themenstarter:in
68 Beiträge seit 2008
vor 14 Jahren
Fehlerhaftes Zeichnen des GUI trotz BGW

Hallo,

altes Spiel: Ich führe einen aufwendigen Prozess aus, möchte dabei aber den GUI weiterhin arbeiten lassen. Also nehme ich mir den BGW und lagere alles soweit aus. Trotzdem hab ich jetzt das Problem, dass der GUI sich nach Abschluss des BGW über den RunWorkerCompleted nicht korrekt neuzeichnet. Blockieren tut der GUI zunächst nicht, er zeichnet Controls beim Darüberbewegen mit der Maus sogar neu. Aber nach wenigen Sekunden blockiert dann alles, ironischerweise zeichnet sich sogar die Taskbar von Windows Vista falsch und überlappt. Beim Öffnen des Kontaktmenüs in der Taskleiste schmiert die Anwendung dann still und heimlich ab, keine Meldung, keine Ahnung. Debug hat nicht viel gebracht, denn die Events des BGW laufen alle sauber durch und beim Pausieren danach zeigt er nur auf Application.Run(...). Irgendwie hab ich das Gefühl, dass der BGW nicht vollständig verarbeitet wird. 😭

Mit freundlichen Grüßen,
pogo

PS: Es handelt sich bei dem "aufwendigen Prozess" eigentlich nur um das Auslesen eines gewählten Verzeichnisses samt Unterverzeichnisse. Und nein, DoEvents() wurde nicht benutzt. 😉

Gelöschter Account
vor 14 Jahren

und beim Pausieren danach zeigt er nur auf Application.Run(...)

falscher thread (nicht im forum sondern in deiner applikation 😉 )?

wenn deine UI dennoch darstellungsfehler hat, dann hast du etwas falsch gemacht. evtl unterbrichst du sie zu häufig, das sie keine zeit hat sich zu rendern?

zeig mal code (nur den relevanten)

RattuS Themenstarter:in
68 Beiträge seit 2008
vor 14 Jahren
        private void GetFiles(string directory, bool subDirectories)
        {
            if (working) return;

            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += new DoWorkEventHandler(GetFilesWorking);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(GetFilesWorkerCompleted);

            if (!worker.IsBusy)
            {
                SetProgress("Getting files of the selected directory...", true);

                imageListIcons.Images.Clear();
                worker.RunWorkerAsync(new object[] { directory, subDirectories });
            }
        }

        private void GetFilesWorking(object sender, DoWorkEventArgs e)
        {
            object[] arguments = (object[])e.Argument;
            string directory = (string)arguments[0];
            bool subDirectories = (bool)arguments[1];

            if (directory.Length <= 0) return;

            BackgroundWorker worker = sender as BackgroundWorker;
            List<ListViewItem> items = new List<ListViewItem>();

            try
            {
                string[] files = Directory.GetFiles(directory);
                foreach (string file in files)
                {
                    FileInfo info = new FileInfo(file);
                    imageListIcons.Images.Add(file, Program.GetIcon(file));

                    ListViewItem item = new ListViewItem(new string[] { Program.CutFileExtension(info.Name), String.Empty, info.Extension.Replace(".", String.Empty).ToUpper(), Program.CovertBytesToUnit(info.Length) }, file);
                    item.Tag = file;
                    items.Add(item);
                }
            }
            catch { }

            if (subDirectories)
            {
                try
                {
                    string[] folders = Directory.GetDirectories(directory);
                    foreach (string folder in folders)
                    {
                        GetSubFiles(folder, items);
                    }
                }
                catch { }
            }

            e.Result = items.ToArray();
        }

        private void GetFilesWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            listViewFiles.BeginUpdate();
            listViewFiles.Items.Clear();
            listViewFiles.Items.AddRange((ListViewItem[])e.Result);
            listViewFiles.EndUpdate();

            SetProgress("Ready", false);
        }

        private void GetSubFiles(string directory, List<ListViewItem> items)
        {
            try
            {
                string[] files = Directory.GetFiles(directory);
                foreach (string file in files)
                {
                    FileInfo info = new FileInfo(file);
                    imageListIcons.Images.Add(file, Program.GetIcon(file));

                    ListViewItem item = new ListViewItem(new string[] { Program.CutFileExtension(info.Name), String.Empty, info.Extension.Replace(".", String.Empty).ToUpper(), Program.CovertBytesToUnit(info.Length) }, file);
                    item.Tag = file;
                    items.Add(item);
                }
            }
            catch { }

            try
            {
                string[] folders = Directory.GetDirectories(directory);
                foreach (string folder in folders)
                {
                    GetSubFiles(folder, items);
                }
            }
            catch { }
        }
J
237 Beiträge seit 2008
vor 14 Jahren

Du greifst aus dem DoWork-Event auf Controls zu. Das darf man niemals tun!
Außerdem wäre es vllt. für die Performance gut das Ergebnis zu puffern und nur alle 25 gefundenen Dateien das GUI zu aktualisieren.

Grüße, JasonDelife.

Beim Programmieren löst man die Probleme, die man nicht hätte, programmierte man nicht.

RattuS Themenstarter:in
68 Beiträge seit 2008
vor 14 Jahren

Stimmt, die ImageList habe ich vergessen auszulagern, aber das ist leider nicht das Problem.

Den GUI aktualisiere ich gar nicht permanent. Ganz im Gegenteil, der GUI bekommt erst am Ende des BGW die Daten in das Control (ListView) übermittelt.

Edit: Ich muss gerade feststellen, dass dieser Zeichenfehler auch ohne BGW vorkommt. Seltsam, könnte das etwas mit Vista zu tun haben?

5.299 Beiträge seit 2008
vor 14 Jahren

Wer so welchen Code schreibt:


            try
            {
               // tue irgendwas
            }
            catch { /* tue nichts */ }

Dem kann man eiglich nicht helfen.
Das unterdrückt jede Fehlermeldung, du kannst also schon prinzipiell keinen Plan haben, was schief läuft.
Die Fehler, die du mitbekommst, _können _"echte" Fehler sein, sind aber wahrscheinlicher Folge-Fehler von Fehlern, die nicht gemeldet wurden - das kann man nicht wissen.

was soll man dir da raten? Deine Fragen haben höchstwahrscheinlich keinen Bezug zum Problem.

Der frühe Apfel fängt den Wurm.

RattuS Themenstarter:in
68 Beiträge seit 2008
vor 14 Jahren

Klasse Kommentar. Hirn ausschalten und einfach mal arrogant drauf losmotzen.

Die IO/Access-Exceptions fange ich natürlich im Catch-Block ab, das sieht man bloß nicht, weil ich die Catches auf { } minimiert habe (der Codeausschnitt ist ohnehin schon so groß). Tu' mir einen Gefallen und drück das große X oben rechts, du bist mir schon mehrfach negativ aufgefallen. Deine Hilfe möchte ich nicht, ErfinderDesRades. Danke für dein Verständnis.

4.221 Beiträge seit 2005
vor 14 Jahren

Der Einwand von ErfinderDesRades war absolut gerechtfertigt... man sieht Deinem Code nicht an, dass Du in den Catches was drin hast...

Und vorallem Umsteiger von VB (nicht .Net) haben in VB mit On error resume next gearbeitet und machen dann in .Net leere Catches...

@pogo nicht gleich beleidigt sein... sonst drücke ich das noch grössere Y und mache hier zu. 😉

Gruss
Programmierhans

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

1.564 Beiträge seit 2007
vor 14 Jahren

Hallo pogo

Ich bin mir jetzt nicht sicher, aber viell. hat's mit der ImageList zu tun. Das ist einer der Komponenten die 1:1 Win32 wrappen. Du fügst für jede Datei ein Item in die Liste hinzu. Wenn die Ordnerstruktur tief ist kann ich mir vorstellen dass Windows ein Problem bekommt intern die ganzen Handles zu verwalten. Versuch' hier mal zu optimieren. Eigentlich musst du nur die Bilder für Extensions wie ".exe", ".ico" und noch ein paar wirklich pro Datei holen für die restlichen Dateien wie ".txt" oder ".doc" reicht eine Referenz die für alle ListViewItems verwendet werden kann.

Grüße
Flo

Blog: Things about Software Architecture, .NET development and SQL Server
Twitter
Google+

Je mehr ich weiß, desto mehr weiß ich was ich noch nicht weiß.

RattuS Themenstarter:in
68 Beiträge seit 2008
vor 14 Jahren

Danke Florian, tatsächlich verursacht die ImageList das Problem. 😃

5.299 Beiträge seit 2008
vor 14 Jahren

@pogo:

Sorry, die Bemerkung hättich in dieser Form vlt. auch sparen können.
Ansonsten kann ich den Code ja nur nehmen, wie er da steht, und leere Catches sind in meinen Augen tatsächlich absolutely No-Go. Das habich mit der gleichzeitig passenden und unpassenden Bemerkung ausgedrückt:

Dem kann man eiglich nicht helfen.

Unpassend, weil ähnelt dem abfälligem Ausdruck "dem kann man nicht mehr helfen", aber ähnelt nur.
Passend, weil ist inhaltlich und wörtlich korrekt: bei Code mit leeren Catches kann man wirklich nicht helfen, da prinzipiell un-debug-bar. Habe ich ja auch differenziert begründet, war also nicht nur Motze.

Naja, ich gelobe Besserung, und dich lass ich fürderhin auch in Ruhe mit meine Kommentare.

Der frühe Apfel fängt den Wurm.