Laden...

Form während threadabarbeitung deaktiveren

Erstellt von BenFire vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.063 Views
B
BenFire Themenstarter:in
50 Beiträge seit 2006
vor 17 Jahren
Form während threadabarbeitung deaktiveren

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
            }
        }

49.485 Beiträge seit 2005
vor 17 Jahren
B
BenFire Themenstarter:in
50 Beiträge seit 2006
vor 17 Jahren

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.

G
87 Beiträge seit 2005
vor 17 Jahren

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.

49.485 Beiträge seit 2005
vor 17 Jahren

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

B
BenFire Themenstarter:in
50 Beiträge seit 2006
vor 17 Jahren

So wunderbar...funktioniert einwandfrei....dankeeeschön 😁