Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Form während threadabarbeitung deaktiveren
BenFire
myCSharp.de - Member



Dabei seit:
Beiträge: 50

Themenstarter:

Form während threadabarbeitung deaktiveren

beantworten | zitieren | melden

Hallo Leute,

ich habe folgendes Problem.
Wenn ich auf einen Button klicke, dann wird ein seperater Thread aufgerufen, der die dahinterliegende Funktion abarbeitet. Soweit so gut. Das funktioniert auch alles.
Aber ich möchte, so lange der Thread abgearbeitet wird alle Button bzw. gleich das gesamte Form sperren, so das der User nicht mittendrin einfach auf Beenden klickt
während der Thread noch ausgeführt wird.

Probiert hab ich das dann damit, dass ich das Fenster per

Mainframe.ActiveForm.Enabled = false
sperre, aber spätestens beim Versuch es wieder zu aktivieren kommt folgende Fehlermeldung:
Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement Mainframe erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

ich bräuchte quasi eine Art globale Variable (des Forms) um das enable von jeder Funktion aus zu steuern.
Oder gibt es da noch eine bessere Lösung für?

Hier mal mein bissheriger Code:


delegate bool DelegateReadATP(FolderBrowserDialog folder); 

private void readATP_Click(object sender, EventArgs e)
       {
             Verarbeitung(folder);
        }  


private void Verarbeitung(FolderBrowserDialog AtpPfad)
        {
            this.Cursor = Cursors.WaitCursor;
            ReadATP newATP = new ReadATP();
            DelegateReadATP read = new DelegateReadATP(newATP.ReadNewATP);
            AsyncCallback callback = new AsyncCallback(CallbackRead);
            //Mainframe.ActiveForm.Enabled = false;   HIER SOLL DIE FORM DEAKTIVIERT WERDEN
            read.BeginInvoke(AtpPfad, callback, null);
        }

private void CallbackRead(IAsyncResult ar) 
        {
            DelegateReadATP read = (DelegateReadATP)ar.AsyncState;
            bool check = read.EndInvoke(ar);

            if (check == true)
            {
              //Mainframe.ActiveForm.Enabled = true; UND HIER SOLL ES WIEDER AKTIVIERT WERDEN
            }
        }
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo BenFire,

[FAQ] Controls von Thread aktualisieren lassen (Invoke-/TreeView-Beispiel)

herbivore
private Nachricht | Beiträge des Benutzers
BenFire
myCSharp.de - Member



Dabei seit:
Beiträge: 50

Themenstarter:

beantworten | zitieren | melden

ja auf der seite war ich auch schon ein paar mal.
ich werd allerdings nicht wirklich schlau daraus.
ich will meine Controlls ja nicht vom thread aktualisieren lassen,
sondern sie wieder freigeben, sobald der thread abgearbeitet ist.
private Nachricht | Beiträge des Benutzers
gehho
myCSharp.de - Member



Dabei seit:
Beiträge: 87
Herkunft: Bonn

beantworten | zitieren | melden

Der Thread ist ja abgearbeitet, wenn der Callback aufgerufen wird. D.h. in deiner Callback-Methode "CallbackRead" musst du das Form wieder auf Enabled setzen. Da die Callback-Methode aber immer noch in dem WorkerThread und nicht im GUI-Thread läuft, musst du an der Stelle mit Invoke arbeiten.

Ungefähr so:


private void CallbackRead(IAsyncResult ar)
        {
            DelegateReadATP read = (DelegateReadATP)ar.AsyncState;
            bool check = (bool) read.EndInvoke(ar); // <-- musste da nicht noch der Cast hin?!

            if (check == true)
            {
              MainFrame.ActiveForm.Invoke( new MethodInvoker( deineFunktionDieActiveFormWiederAufEnabledSetzt ) );
            }
        }

Durch das Invoke wird der Methodenaufruf in den Thread, in dem MainFrame.ActiveForm deklariert wurde, gemarshalled. Das heißt, dein Re-Enablen des Fenster geschieht letztlich im GUI-Thread.
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo BenFire,

jeder Zugriff, auch das Zerstören eines Controls muss von dem Thread aus erfolgen, der es erzeugt hat. Durch Control.Invoke kann man erreichen, dass der Code von diesem Thread aus aufgerufen wird.

herbivore
private Nachricht | Beiträge des Benutzers
BenFire
myCSharp.de - Member



Dabei seit:
Beiträge: 50

Themenstarter:

beantworten | zitieren | melden

So wunderbar...funktioniert einwandfrei....dankeeeschön
private Nachricht | Beiträge des Benutzers