Thread benutzen wie
-
In dem du sie in die IDE eintippst?
Wie gesagt, du kannst deine C++ Funktionen weiter nutzen! - Musst diese nur in eine DLL kompilieren.
Anschließend kannst du diese mittels P/invoke aus C# heraus aufrufen.
Ich hoffe deine Frage bzgl. der Methode war ein Witz...
-
Sind Methoden dass selbe wie Funktionen? Warum sollte ich C# verwenden, wenn ich meine Funktionen ohne probleme und ohne das ich sie in eine Dll Datei packen muss in Visual C++ verwenden kann. Außerdem hab ich mir extra ein Buch zum Visual C++ lernen gekauft. Visual C++ gefällt mir halt.
-
Jim20115 schrieb:
Sind Methoden dass selbe wie Funktionen?
Nicht ganz, aber so etwas ähnliches - Funktionen stehen frei im Raum, Methoden gehören zu einer Klasse.
PS: Was immer du vorhast, entscheide dich bitte für eine Sprache.
-
Ich hab gelesen das der zugrif von einem auf den anderen Thread durch delegate funktionirt. kennt irgendjemand ein gutes Tutorial das beschreibt wie man das mit Visual C++ macht ?
-
Jim20115 schrieb:
Ich hab gelesen das der zugrif von einem auf den anderen Thread durch delegate funktionirt. kennt irgendjemand ein gutes Tutorial das beschreibt wie man das mit Visual C++ macht ?
Ich nehme an dabei geht es um den Zugriff aus einem nicht-UI Thread auf das UI:
Benutze dazu einfach Control::Invoke(..). MSDN hat da mehr Infos und Beispiele findest Du bestimmt auch zu genüge (ev. für C# suchen).
-
Ich hab folgendes Programm geschrieben. Es zeigt eine Textbox und ein Knopf an wenn man auf den Knopf drückt soll ein Thread erzeugt werden. Der aa in die Textbox schreibt. Wenn ich das Programm ausführe und den Knopf drücke hängt sich das Programm auf. Warum hängt es sich auf wo ist der fehler?
#include<Windows.h> #pragma once namespace Thread1 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Zusammenfassung für Form1 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Konstruktorcode hier hinzufügen. // } protected: /// <summary> /// Verwendete Ressourcen bereinigen. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Button^ button1; static System::Windows::Forms::TextBox^ s; protected: public: /// <summary> /// Erforderliche Designervariable. /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// </summary> void InitializeComponent(void) { this->button1 = (gcnew System::Windows::Forms::Button()); this->s = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // // button1 // this->button1->Location = System::Drawing::Point(13, 26); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::t); // // s // this->s->Location = System::Drawing::Point(35, 98); this->s->Name = L"s"; this->s->Size = System::Drawing::Size(100, 20); this->s->TabIndex = 1; // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->s); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion delegate void Delg_1(int zahl_1); static void update_1(int zahl_1) { if(Thread1::Form1::s->InvokeRequired) { Thread1::Form1::Delg_1^a=gcnew Delg_1(update_1); a->Invoke(1); } else { Thread1::Form1::s->Text = "aa"; } } static void PR (Object^u) { update_1(1); } private: System::Void t(System::Object^ sender, System::EventArgs^ e) { HANDLE tr; DWORD N; Threading::Thread^ newThread = gcnew Threading::Thread(gcnew Threading::ParameterizedThreadStart(this->PR)); newThread->Start(); ; } }; }
Ich bekomm folgende Fehlermeldung
"Thread.exe" (Verwaltet (v4.0.30319)): "C:\WINDOWS\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll" geladen
"Thread.exe" (Verwaltet (v4.0.30319)): "C:\Thread\11\Release\Thread.exe" geladen, Symbole geladen.
"Thread.exe" (Verwaltet (v4.0.30319)): "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll" geladen
"Thread.exe" (Verwaltet (v4.0.30319)): "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll" geladen
"Thread.exe" (Verwaltet (v4.0.30319)): "C:\WINDOWS\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll" geladen
Eine nicht behandelte Ausnahme des Typs "System.StackOverflowException" ist in System.Windows.Forms.dll aufgetreten.Das Programm "[2404] Thread.exe: Verwaltet (v4.0.30319)" wurde mit Code 1073807364 (0x40010004) beendet.
-
Zeile 100 enthält den Fehler.... du machst da was ganz falsches...
Auch solltest Du vermeiden mit statischen Fields/Methoden zu arbeiten... warum machst Du das? Es gibt keinen Grund dafür...
-
Was ist an zeile 100 dert verkert. wenn ich die beiden Funktionen nicht als static kennzeichne wird die updat funktion nicht vom Delegartor angenom. Und ich kann keinen Thread aus einer nicht statischen Funktion bilden weil es dann ebenfals eine Fehlermeldung gibt. Wie mach ich das richtig?
-
Jim20115 schrieb:
Was ist an zeile 100 dert verkert. wenn ich die beiden Funktionen nicht als static kennzeichne wird die updat funktion nicht vom Delegartor angenom. Und ich kann keinen Thread aus einer nicht statischen Funktion bilden weil es dann ebenfals eine Fehlermeldung gibt. Wie mach ich das richtig?
Schau Dir einfach mal an, wie man Delegaten mit nicht-statischen Member Funktionen verbindet.
-
In Zeile 100 rufst Du einfach nur den Delegate auf... das wolltest Du IMHO nicht... sondern ein "Invoke oder BeginInvoke" vom Control aufrufen und nicht vom Delegate...
Aber wie gesagt: Mach es *ohne* static, dann wird es auch einfacher...
-
Ich habs hingekrigt. Mein Programm sieht so aus.
#include<Windows.h> int c=0; #pragma once namespace Thread1 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Zusammenfassung für Form1 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Konstruktorcode hier hinzufügen. // } protected: /// <summary> /// Verwendete Ressourcen bereinigen. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Button^ button1; static System::Windows::Forms::TextBox^ s; protected: public: /// <summary> /// Erforderliche Designervariable. /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// </summary> void InitializeComponent(void) { this->button1 = (gcnew System::Windows::Forms::Button()); this->s = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // // button1 // this->button1->Location = System::Drawing::Point(13, 26); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::t); // // s // this->s->Location = System::Drawing::Point(35, 98); this->s->Name = L"s"; this->s->Size = System::Drawing::Size(100, 20); this->s->TabIndex = 1; // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->s); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion delegate void Delg_1(int zahl_1); Threading::Thread^ newThread; static void update_1(int zahl_1) { if(Thread1::Form1::s->InvokeRequired) { Thread1::Form1::Delg_1^a=gcnew Delg_1(update_1); Thread1::Form1::s->Invoke(a,1); } else { Thread1::Form1::s->Text = "aa"; } } void PR () { Thread1::Form1::Delg_1^a=gcnew Delg_1(update_1); Thread1::Form1::s->Invoke(a,1); } private: System::Void t(System::Object^ sender, System::EventArgs^ e) { HANDLE tr; DWORD N; newThread = gcnew Threading::Thread(gcnew Threading::ThreadStart(this,&Thread1::Form1::PR)); newThread->Start(); ; } }; }
Wie kann ich den Thread von einem anderen Thread aus beenden?
-
Und jetzt mach nich das "static" weg, dann sieht es gar nicht mal so schlecht aus...
Der Thread wird doch bei Dir sofort beenden... was willst DU da noch beenden?
Ansonsten würde ich es mit einem AutoResetEvent machen....
-
Ich meinte ja auch wenn ich in den Thread eine Endlosschleife hätte. Gibt es ein Befel den ich einen Thread übergeben kann der diesen dann beendet. Ist es möglich von einem anderen Thread aus werte an einen anderen Threat zu schicken. Am besten strings?
-
Du kannst mit Events oder ähnlichem Nachrichten zwischen den Threads austauschen - und mit der nötigen Sorgfalt zur Synchronisation kannst du auch Variablen nutzen, die beide Seiten sehen können (z.B. Member der Thread-Klasse).
Ansonsten ist es problematisch, einen Thread von außen abzuschießen. Wenn er nicht gerade Amok läuft, solltest du es dem Thread selber überlassen, wann und wie er sauber beendet werden kann.
-
Genauer gesagt: Es ist sehr schlecht einen Thread "abzuschiessen"... dies kann u.a. zum Dead-Lock in Deinem Programm führen... siehe mein Blog... http://blog.kalmbachnet.de/?postid=6
-
Kann ich Variablen die ich im Hauptprogramm erzeuge. Von mehreren Threads gleichzeitig lesen lassen ohne das es Probleme giebt. Ist es auch möglich dass eine Variable die im Hauptprogramm erzeugt wurde von mehreren Threads gleichzeitig beschrieben wird?
-
Wenn du richtig synchronisierst kann und darf der Fall nicht eintreten, dass mehrere Threads auf einem Objekt schreiben oder einer schreibt während ein anderer liest.
-
Wie syncronisier ich die threads. Ich hab ein Programm geschrieben bei demm es einen Knopf und ein Textfeld giebt. Beim Drücken auf dem Knopf wird ein Thread gestartet in dem eine Schleife läuf die überprüft ob z=1 ist. Sie läuft solange bis z=0 ist. Auserdem wird beim Knopfdruck z auf 1 gesetzt. Der Thread schreibt mit hilfe0 von Delegate aa ins Textfeld. Wenn man ein weiteresmal auf dem Knopf drückt wird z auf 0 gesetzt. Und somit Die schlleife im Thread beended. Wodurch der Thread auch beendet wird. Das Programm läuft ohne Fehler. Muss ich da noch irgendwas syncronisieren wenn ja wie?
Hier das Programm
#include<Windows.h> int c=0; int z=1; #pragma once namespace Thread1 { using namespace System; using namespace System::ComponentModel; using namespace System::Collections; using namespace System::Windows::Forms; using namespace System::Data; using namespace System::Drawing; /// <summary> /// Zusammenfassung für Form1 /// </summary> public ref class Form1 : public System::Windows::Forms::Form { public: Form1(void) { InitializeComponent(); // //TODO: Konstruktorcode hier hinzufügen. // } protected: /// <summary> /// Verwendete Ressourcen bereinigen. /// </summary> ~Form1() { if (components) { delete components; } } private: System::Windows::Forms::Button^ button1; static System::Windows::Forms::TextBox^ s; protected: public: /// <summary> /// Erforderliche Designervariable. /// </summary> System::ComponentModel::Container ^components; #pragma region Windows Form Designer generated code /// <summary> /// Erforderliche Methode für die Designerunterstützung. /// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden. /// </summary> void InitializeComponent(void) { this->button1 = (gcnew System::Windows::Forms::Button()); this->s = (gcnew System::Windows::Forms::TextBox()); this->SuspendLayout(); // // button1 // this->button1->Location = System::Drawing::Point(13, 26); this->button1->Name = L"button1"; this->button1->Size = System::Drawing::Size(75, 23); this->button1->TabIndex = 0; this->button1->Text = L"button1"; this->button1->UseVisualStyleBackColor = true; this->button1->Click += gcnew System::EventHandler(this, &Form1::t); // // s // this->s->Location = System::Drawing::Point(35, 98); this->s->Name = L"s"; this->s->Size = System::Drawing::Size(100, 20); this->s->TabIndex = 1; // // Form1 // this->AutoScaleDimensions = System::Drawing::SizeF(6, 13); this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font; this->ClientSize = System::Drawing::Size(292, 266); this->Controls->Add(this->s); this->Controls->Add(this->button1); this->Name = L"Form1"; this->Text = L"Form1"; this->ResumeLayout(false); this->PerformLayout(); } #pragma endregion delegate void Delg_1(int zahl_1); Threading::Thread^ newThread; static void update_1(int zahl_1) { if(Thread1::Form1::s->InvokeRequired) { Thread1::Form1::Delg_1^a=gcnew Delg_1(update_1); Thread1::Form1::s->Invoke(a,1); } else { Thread1::Form1::s->Text = "aa"; } } void PR () { while(z) { Thread1::Form1::Delg_1^a=gcnew Delg_1(update_1); Thread1::Form1::s->Invoke(a,1); } } private: System::Void t(System::Object^ sender, System::EventArgs^ e) { HANDLE tr; DWORD N; c=c+1; if(c>1) { c=0; } if(c==1) { z=1; newThread = gcnew Threading::Thread(gcnew Threading::ThreadStart(this,&Thread1::Form1::PR)); newThread->Start(); } else { z=0; } ; } }; }
-
Hallo Hört mich jemand wie synchronisiere ich den zugriff auf die selben Variablen?
-
Jim20115 schrieb:
Hallo Hört mich jemand wie synchronisiere ich den zugriff auf die selben Variablen?
Es gibt drei Wege:
a.) Du marschallst mit Control.Invoke(..) alle Aufrufe auf denselben Thread
b.) Du benutzt Locking (mit System::Threading::Monitor o.ä.)
c.) Du benutzt Events (mit System::Threading::ManualResetEvent / AutoResetEvent o.ä.)