kostenloser Webspace werbefrei: lima-city


C#: Problem mit Thread

lima-cityForumProgrammiersprachenProgrammieren mit .NET & Mono

  1. Autor dieses Themas

    yorecords

    Kostenloser Webspace von yorecords

    yorecords hat kostenlosen Webspace.

    Hallo!

    Folgendes Problem: Nachdem der Inhalt eines Fensters fertig geladen ist, soll intern eine Aktualisierung stattfinden. Natürlich in einem eigenen Thread, damit der User nicht warten muss. Und das mit dem Thread funktioniert in diesem Fall leider nicht.
    Wenn ich den Thread ohne Timer starte, wird die Aktion ausgeführt während der Inhalt des Fensters noch nicht geladen ist und das Laden wird für diese Zeitspanne blockiert. Des Weiteren erfüllt der Thread auch anderweitig nicht seine Funktion, da man währenddessen nichts machen kann.. Mit Timer ist es das Gleiche, nur dass halt der Inhalt vorher geladen wird..
    Diese Aktualisierung kann aber auch manuell durchgeführt werden, und auf diese Weise funktioniert auch alles wunderbar. Ich frage mich jetzt warum der Thread dann so nicht will..
    Hier mal dazu ein Ausschnitt aus dem Code:

    private void tabPage2_Enter(object sender, EventArgs e)
            {
                Thread rThread = new Thread(refresh);
                rThread.Start();
            }
    
            private void refresh()
            {
                this.Invoke(new Action(refreshThread));
            }
    
            private void refreshThread()
            {
                Blaah blaah blaah...
            }


    Das manuelle Aktualisiseren funktioniert auf die komplett gleiche Weise, nur dass der Inhalt da schon komplett geladen ist. Und nach dieser Logik sollte es doch so mit Timer funktionieren.. Ich habe es sowohl mit dem Forms Timer als auch dem Threading Timer versucht, aber mit dem gleichen Ergebnis.
    Weiß jemand was ich da falsch mache?

    Danke im Voraus!

    Edit:
    Und so ganz nebenbei: Weiß jemand warum bei mir Dispatcher nicht erkannt wird? Normal müsste ich ja this.Dispatcher.Invoke(new Action(refreshThread)); schreiben..

    Beitrag zuletzt geändert: 12.8.2012 1:53:47 von yorecords
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. Hallo yorecords,

    ich denke mal, dass 'this' irgendein Gui-Control ist. Was bei Deinem Code passiert ist das folgende:
    tabPage2_Enter() startet einen Thread. Dieser Thread startet dann die Ausführung von refreshThread() mittels Invoke(), d.h. der Thread sendet eine Nachricht an den Haupt- bzw. Gui-Thread, dass er refreshThread() ausführen soll. Daher wird refreshThread() nicht im erzeugten Thread sondern im Haupthread durchgeführt, weshalb die Gui einfriert.
    Was die Sache mit dem Dispatcher angeht, vermute ich, dass Dein Control von System.Windows.Forms.Control abgeleitet ist und daher zwar über Invoke(), BeginInvoke(), EndInvoke(), usw. verfügt aber keinen Dispatcher-Member hat. Bei WPF-Controls scheint das anders zu sein.
  4. Autor dieses Themas

    yorecords

    Kostenloser Webspace von yorecords

    yorecords hat kostenlosen Webspace.

    darkpandemic schrieb:
    Hallo yorecords,

    ich denke mal, dass 'this' irgendein Gui-Control ist. Was bei Deinem Code passiert ist das folgende:
    tabPage2_Enter() startet einen Thread. Dieser Thread startet dann die Ausführung von refreshThread() mittels Invoke(), d.h. der Thread sendet eine Nachricht an den Haupt- bzw. Gui-Thread, dass er refreshThread() ausführen soll. Daher wird refreshThread() nicht im erzeugten Thread sondern im Haupthread durchgeführt, weshalb die Gui einfriert.
    Was die Sache mit dem Dispatcher angeht, vermute ich, dass Dein Control von System.Windows.Forms.Control abgeleitet ist und daher zwar über Invoke(), BeginInvoke(), EndInvoke(), usw. verfügt aber keinen Dispatcher-Member hat. Bei WPF-Controls scheint das anders zu sein.


    Danke für deine Antwort!
    Ich verstehe... Ja so wird es wohl sein. Als ich Dispatcher das letzte mal verwendet habe war das in einer WPF Anwendung...
    Hast du zufällig noch eine Idee wie ich das Problem dann lösen kann? In WPF würde das so ohne Probleme funktionieren..
  5. Hallo yorecords,

    wenn Du verrätst, was Dein 'this' ist bzw. was 'blaah blaah blaah' in refreshThread() ist, dann könnte man schauen, in welcher Weise es sich asynchron machen lässt. Funktioniert den der Code in refreshThread() nicht, wenn Du Ihn im Thread ausführst?
  6. Autor dieses Themas

    yorecords

    Kostenloser Webspace von yorecords

    yorecords hat kostenlosen Webspace.

    darkpandemic schrieb:
    Hallo yorecords,

    wenn Du verrätst, was Dein 'this' ist bzw. was 'blaah blaah blaah' in refreshThread() ist, dann könnte man schauen, in welcher Weise es sich asynchron machen lässt. Funktioniert den der Code in refreshThread() nicht, wenn Du Ihn im Thread ausführst?


    Also das 'this' erfüllt in diesem Fall eigentlich keinen Zweck.. Ich hab mir nur angewöhnt es dazuzuschreiben.
    Das blaah blaah blaah ist eine Verbindung zu einer Datenbank die Daten in ein DataGridView lädt und nebenbei 2 ProgressBars bewegt.
    Der Code in refreshThread() funktioniert schon, nur wird das Programm während des Vorgangs blockiert, also gleich wie ohne eigenem Thread.

    Beitrag zuletzt geändert: 14.8.2012 14:38:36 von yorecords
  7. Hallo yorecords,

    an dem 'this' wäre interessant gewesen, um welchen Datentyp es sich den handelt. Es hätte ja ein Browser-Control oder sonst was sein können, was evtl. von sich aus eine asynchrone Update-Methode mitbringt. Aber zumindest weiß ich ja jetzt schon mal, dass es sich um ein DataGridView-Control handelt.
    Jetzt wäre es an und für sich gut zu wissen, wie Du den die neuen Daten für das Control besorgst:
    - Ist das Control fest an eine Datenquelle gebunden?
    - Werden die Daten mit Hilfe eines DataReader abgerufen?
    - Wird ein DataAdapter verwendet um daraus ein DataSet zu generieren?
    Je nachdem was nun davon zutrifft kann man mehr oder weniger viel in den Background Worker packen. Auf jeden Fall solltest Du nur die Aktualisierung der ProgressBars und evtl. das neu belegen des GridView.DataSource-Attributes per Invoke() an den Haupthread delegieren.

    Edit:
    Sofern das Control nicht gebunden ist würde ich wie folgt vorgehen:
    - Im Thread mittels DataReader und DataAdapter ein DataSet befüllen (alles ohne Invoke())
    - Wenn die Daten vollständig sind, d.h. wenn DataAdapter.Fill() zurückkehrt, mittels Invoke() das setzen des GridViewControl.DataSource-Attributes auf das neu erzeugte DataSet-Objekt an den Hauptthread delegieren.

    Beitrag zuletzt geändert: 14.8.2012 22:15:25 von darkpandemic
  8. Autor dieses Themas

    yorecords

    Kostenloser Webspace von yorecords

    yorecords hat kostenlosen Webspace.

    darkpandemic schrieb:
    Hallo yorecords,

    an dem 'this' wäre interessant gewesen, um welchen Datentyp es sich den handelt. Es hätte ja ein Browser-Control oder sonst was sein können, was evtl. von sich aus eine asynchrone Update-Methode mitbringt. Aber zumindest weiß ich ja jetzt schon mal, dass es sich um ein DataGridView-Control handelt.
    Jetzt wäre es an und für sich gut zu wissen, wie Du den die neuen Daten für das Control besorgst:
    - Ist das Control fest an eine Datenquelle gebunden?
    - Werden die Daten mit Hilfe eines DataReader abgerufen?
    - Wird ein DataAdapter verwendet um daraus ein DataSet zu generieren?
    Je nachdem was nun davon zutrifft kann man mehr oder weniger viel in den Background Worker packen. Auf jeden Fall solltest Du nur die Aktualisierung der ProgressBars und evtl. das neu belegen des GridView.DataSource-Attributes per Invoke() an den Haupthread delegieren.

    Edit:
    Sofern das Control nicht gebunden ist würde ich wie folgt vorgehen:
    - Im Thread mittels DataReader und DataAdapter ein DataSet befüllen (alles ohne Invoke())
    - Wenn die Daten vollständig sind, d.h. wenn DataAdapter.Fill() zurückkehrt, mittels Invoke() das setzen des GridViewControl.DataSource-Attributes auf das neu erzeugte DataSet-Objekt an den Hauptthread delegieren.


    Yeeeeh perfekt! :prost:
    Vielen Dank für deine Hilfe! So funktioniert es.
    Hab erst vor Kurzen angefangen mit Threads zu arbeiten und hab nicht gewusst, dass man nur die einzelnen Zugriffe invoken darf..

    Beitrag zuletzt geändert: 14.8.2012 22:52:09 von yorecords
  9. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!