Threading mit CLI und Delegatinstanz



  • Servus!
    Ich bin gerade dabei mein kleines Progrämmchen (~4000 Zeilen) auf Multitasking umzustellen. Denn während er die Berechnungen macht, wird das Hauptfenster nicht neu gezeichnet und somit besteht auch nicht die Möglichkeit den Cancel Button zu drücken.
    Daher würde ich gerne meine Funktion calculate() als Thread laufen lassen.
    Ich habs mit folgendem Befehl probiert:

    Thread::Start(&WlanPositionSystem::Form1::calculate());
    

    Allerdings bekomme ich jetzt immer die Fehlermeldung:
    "error C3374: Adresse von "WlanPositionSystem::Form1::calculate" kann nur übernommen werden, wenn eine Delegatinstanz erstellt wird."

    Also, was muss ich machen damit das funktioniert und was ist eine Delegatinstanz?

    Danke schon mal im vor raus!
    Mit freundlichen Grüßen 🙂





  • Danke für den Link, aber das hilft mir auch nicht wirklich weiter 😞
    Ich bekomm weiterhin Fehlermeldungen...
    Ist es überhaupt technisch möglich einen Thread zu erstellen, der eine Methode einer Klasse ausführt und über eine andere Methode der selben Klasse gestartet wird?
    Meine Klasse ist die FORM1 (jaja VS, i know :D)
    die Methoden lauten einmal calculate(); und einmal click_button();
    Wenn jetzt click_button(); ausgeführt wird, soll halt ein neuer Thread erstellt werden der die Funktion calculate() ausführt.
    Das sollte doch eigentlich ganz einfach funktionieren.
    Mein Ansatz:

    Void click_button(System::Object^  sender, System::EventArgs^  e) 
    {
        ThreadStart^ starte = ThreadStart(&WlanPositionSystem::Form1::calculate);
        Thread^ myThread = gcnew Thread::Thread(starte);
        myThread->Start();
    }
    


  • teddds schrieb:

    ThreadStart^ starte = ThreadStart(&WlanPositionSystem::Form1::calculate);
    

    wie wäre es mit gcnew ThreadStart() ??



  • wie wäre es mit gcnew ThreadStart() ??

    danke!

    jetzt bekomme ich folgende fehlermeldung
    "error C3350: "System::Threading::ThreadStart": Ein Delegatkonstruktor erwartet 2 Argument(e)."

    Was für Argumente sind das? Ich mein, der brauch doch nur wissen, welche Funktion der Starten soll, oder?

    Edit:
    Habs jetzt selber hinbekommen!
    so funktionierts jetzt:

    Thread^ Thread_calc = gcnew Thread( gcnew ThreadStart( this,&Form1::calculate));
    Thread_calc->Start();
    


  • Servus,

    mein Thread Thread_calc starte zwar jetzt einwandfrei, verursacht aber dann eine exception. Ich habe mich ein wenig belesen und herausgefunden, das mein Thread_calc keine Zugriffsrechte zu Änderung der Steuerelemente hat. Das ist nur dem Thread möglich der diese Elemente auch erstellt hat.
    Also muss ich mittels invoke den Thread der die Steuerlemente erstellt hat mitteilen das er was ändern soll.
    Okay soweit so gut.

    Ich habe eine Funktion void buttons_on(); und void buttons_off(); die zu beginn und ende meines Thread_calc aufgerufen werden.
    Ich hab nun versucht den Aufruf mittels

    Control::Invoke(&Form1::buttons_on);
    

    zu realisieren.
    Jedoch meint VS das Form1::buttons_on nur übernommen werden kann, wenn eine Delegatinstanz erstellt wird.
    Wie geht das? Und welcher Zweck steht dahinter? Möchte das endlich mal verstehen weil mich diese Fehlermeldung immer wieder übern Weg läuft und ich jedesmal nur mit einem Work-A-Round weiter komme. Und bitte keine Verlinkungen zu MSDN - das hab ich schon gelesen und nicht wirklich verstanden 😞



  • Control::Invoke(gcnew System::Action(&Form1::buttons_on)); // oder so ähnlich
    


  • mogel schrieb:

    Control::Invoke(gcnew System::Action(&Form1::buttons_on)); // oder so ähnlich
    

    Gibt folgende Fehlermeldung:
    Fehler 1 error C2955: "System::Action": Für die Verwendung der generic-Klasse ist eine generic-Argumentliste erforderlich.

    Fehler 2 error C3352: "void WlanPositionSystem::Form1::ButtonsOff(void)": Die angegebene Funktion stimmt nicht mit dem Delegattyp "void (T)" überein.

    EDIT: So alle Probleme behoben.
    Für alle die auch mal betreffen sollte, hier die Lösung um Steuerelemente und die Textbox von einem Thread aus zu benutzen:

    delegate void InvokeDelegate();
    delegate void SetTextDelegate(String^ text, int modus);
    void SetTextInformation(String^ text, int modus)
    {
    	if (this->InformationTextBox->InvokeRequired)
    		{
    			this->Invoke(gcnew SetTextDelegate(this, &Form1::SetTextInformation),text,modus);
    		}
    	else
    		{
    			if(modus==1)
    				{
    					this->InformationTextBox->Text = text;
    				}
    			else
    				{
    					this->InformationTextBox->AppendText(String::Format("{0}",text));										
    				}
    		}
    }
    

    in im Thread selber wird das ganze dann folgender Maßen aufgerufen:

    Control::Invoke(gcnew InvokeDelegate(this, &Form1::ButtonsOff));
        this->SetTextInformation("",1);
    

Anmelden zum Antworten