Threading





  • Leider auch kein Erfolg -.-



  • C++Lerner schrieb:

    Leider auch kein Erfolg -.-

    Es gibt ja sogar ein Bsp. auf der von mir geposteten MSDN Seite.
    Simon



  • Ich Blick da nicht durch (@ Invoke).
    Hab überhaupt keine Idee, wie ich das umsetzen soll:

    // The following code assumes a 'ListBox' and a 'Button' control are added to a form,
    // containing a delegate which encapsulates a method that adds items to the listbox.
    public ref class MyThreadClass
    {
    private:
       MyFormControl^ myFormControl1;
    
    public:
       MyThreadClass( MyFormControl^ myForm )
       {
          myFormControl1 = myForm;
       }
    
       void Run()
       {
          // Execute the specified delegate on the thread that owns
          // 'myFormControl1' control's underlying window handle.
          myFormControl1->Invoke( myFormControl1->myDelegate );
       }
    };
    

    Mein Versuch:

    public ref class MyThreadClass
    {
    private:
       ProgressBar^ PB;
    

    Das war´s, ab hier blick ich nicht mehr durch 🙄

    public:
       MyThreadClass( MyFormControl^ myForm )
       {
          myFormControl1 = myForm;
       }
    
       void Run()
       {
          myFormControl1->Invoke( myFormControl1->myDelegate );
       }
    };
    




  • Da ist wieder so viel Schnick-Schnack drin, bracuhe was ganz einfaches^^

    Könnte mir jemand vllt ein ganz knappes Beispiel geben ? Ohne Schnick-Schnack, wäre sehr nett.



  • Ist da viel drin??? 😕 musst halt die anderen Sprachen abschalten, ich finde da ist sowieso nur das nötigste drin...



  • xD, ja ist mir schon klar, ich meine der Quellcode sieht ziemlich voll aus o.O



  • Ich poste jetzt einfach mal meinen kompletten Header:

    #pragma once
    
    namespace t2 {
    
    	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
    	///
    	/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
    	///          die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
    	///          das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
    	///          Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
    	///          arbeiten, die diesem Formular zugewiesen sind.
    	/// </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;
    	private: System::Windows::Forms::ProgressBar^  progressBar1;
    	protected: 
    
    	private:
    		/// <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->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
    			this->SuspendLayout();
    			// 
    			// button1
    			// 
    			this->button1->Location = System::Drawing::Point(12, 81);
    			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::button1_Click);
    			// 
    			// progressBar1
    			// 
    			this->progressBar1->Location = System::Drawing::Point(12, 158);
    			this->progressBar1->Name = L"progressBar1";
    			this->progressBar1->Size = System::Drawing::Size(260, 23);
    			this->progressBar1->TabIndex = 1;
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(284, 264);
    			this->Controls->Add(this->progressBar1);
    			this->Controls->Add(this->button1);
    			this->Name = L"Form1";
    			this->Text = L"Form1";
    			this->ResumeLayout(false);
    
    		}
    #pragma endregion
    
    	private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
    			 {
    				 System::Threading::Thread^ T1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1::Do));
    				 T1->Start();
    			 }
    
    	private: void Do()
    			 {
    				 progressBar1->Value = 50;
    			 }
    	};
    }
    

    Der Wille ist ja wahrscheinlich klar, die Umsetzung falsch.
    Ich weiß UI-Thread, aber ich hab keine Ahnung 😕 😕
    Wäre wirklich nett, wenn mir jemand den Code so umschreiben könnte, dass er funktioniert. So lern ich das wahrscheinlich am besten ! 🙂



  • private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
    		 {
    			 System::Threading::Thread^ T1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1::Do));
    			 T1->Start();
    		 }
    
    private: delegate void DoDelegate();
    
    private: void Do()
    		 {
    			 if (!InvokeRequired)
    			 {
    				progressBar1->Value = 50;
    			 }
    			 else
    			 {
    				 Invoke(gcnew DoDelegate(this, &Form1::Do));
    			 }
    		 }
    };
    


  • Super !
    Hat geklappt, danke !

    Jetzt werde ich mal zusehen, dass ich den ganzen Code noch verstehe, sollte aber kein Problem sein !

    Danke nochmal an alle 😃



  • Hallo,

    eine weiter Möglichkeit (nicht unbedingt ratsam) den Fehler

    Threadübergreifender Zugriff auf Steuerelement

    wegzubekommen, ist z.B. im Konstruktor der Form1 folgendes hinzuzufügen:

    Form1::CheckForIllegalCrossThreadCalls=false;
    

    Jetzt aber zu meiner Frage:
    Ich hab das Beispiel eben auch mal ausprobiert (1:1 übernommen) und hatte eigentlich erwartet, dass das Fenster (also die Form1) nicht blockiert!
    Deswegen bette ich die Methode Do() ja in einen eigenen Thread, oder nicht?
    Bei mir blockiert das Fenster trotzdem, bis mein Testzähler durchgelaufen ist.

    rufe ich die Methode Do() so auf:

    ...
    	private: 
    		System::Void btn_Click(System::Object^  sender, System::EventArgs^  e)
    		{
    			System::Diagnostics::Debug::WriteLine("CLICK");
    			Do();
    		}
    
    		delegate void DoDelegate(); 
    
    		void Do()
    		{			
    				int i=0;
                    while(i<200)
    				{
    					System::Diagnostics::Debug::Write("Do it ");
    					System::Diagnostics::Debug::WriteLine(i);
    					i++;
    				}
    		}
    	};// end class Form1
    
    } // end namespace
    

    verhält sie sich bei mir exakt so wie das obige Beispiel 😕



  • Hm...ist bei mir auch so ( hab es vorhin erst richtig ausprobiert, hatte kaum Zeit... )

    Frage:

    Form1::CheckForIllegalCrossThreadCalls=false;
    

    Hat das irgendwelche Nebenwirkungen ???

    Ich poste gleich mal meinen gesammten Header, dann kann ja vllt mal jemand verbesserungsvorschläge geben, damit die Form1 nicht so lagt...



  • Hier der komplette Code (Soll mal ein kleiner DownloadManager werden :D)
    Ist leider etwas mehr und aus welchem grund auch immer sehr ungeordnet -.-

    #pragma once
    
    namespace DownloadManager {
    
    	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
    	///
    	/// Warnung: Wenn Sie den Namen dieser Klasse ändern, müssen Sie auch
    	///          die Ressourcendateiname-Eigenschaft für das Tool zur Kompilierung verwalteter Ressourcen ändern,
    	///          das allen RESX-Dateien zugewiesen ist, von denen diese Klasse abhängt.
    	///          Anderenfalls können die Designer nicht korrekt mit den lokalisierten Ressourcen
    	///          arbeiten, die diesem Formular zugewiesen sind.
    	/// </summary>
    	public ref class Form1 : public System::Windows::Forms::Form
    	{
    	public:
    
    		System::Collections::Generic::Dictionary<String^,String^> ^Container1;
    		String^ Pfad;
    		int Counter;
    	private: System::Windows::Forms::Label^  label7;
    	public: 
    	private: System::Windows::Forms::Label^  label6;
    			 int Counter_max;
    
    		Form1(void)
    		{
    			InitializeComponent();
    			Container1 = gcnew System::Collections::Generic::Dictionary<String^,String^>;
    			Counter = 0;
    			//
    			//TODO: Konstruktorcode hier hinzufügen.
    			//
    		}
    
    	protected:
    		/// <summary>
    		/// Verwendete Ressourcen bereinigen.
    		/// </summary>
    		~Form1()
    		{
    			if (components)
    			{
    				delete components;
    			}
    		}
    	private: System::Windows::Forms::Panel^  panel1;
    	private: System::Windows::Forms::Button^  btn_Min;
    	protected: 
    
    	private: System::Windows::Forms::Button^  btn_Exit;
    
    	private: System::Windows::Forms::GroupBox^  groupBox1;
    	private: System::Windows::Forms::Panel^  panel2;
    	private: System::Windows::Forms::Label^  label1;
    	private: System::Windows::Forms::GroupBox^  groupBox2;
    	private: System::Windows::Forms::TextBox^  tb_Pfad;
    
    	private: System::Windows::Forms::Panel^  panel3;
    	private: System::Windows::Forms::Button^  btn_Add;
    
    	private: System::Windows::Forms::TextBox^  tb_Dateiname;
    
    	private: System::Windows::Forms::Label^  label2;
    	private: System::Windows::Forms::TextBox^  tb_Url;
    
    	private: System::Windows::Forms::Label^  label3;
    	private: System::Windows::Forms::ListBox^  lb_Files;
    
    	private: System::Windows::Forms::GroupBox^  groupBox3;
    	private: System::Windows::Forms::Panel^  panel5;
    	private: System::Windows::Forms::Panel^  panel4;
    	private: System::Windows::Forms::Label^  label5;
    	private: System::Windows::Forms::Label^  label4;
    	private: System::Windows::Forms::ProgressBar^  PB_Current;
    	private: System::Windows::Forms::Button^  btn_Start;
    
    	private: System::Windows::Forms::Label^  lbl_T_Downloaded;
    
    	private: System::Windows::Forms::Label^  lbl_T_Übertragen;
    
    	private: System::Windows::Forms::Label^  lbl_C_Gesammt;
    
    	private: System::Windows::Forms::Label^  lbl_C_Übertragen;
    
    	private: System::Windows::Forms::StatusStrip^  statusStrip1;
    	private: System::Windows::Forms::ToolStripStatusLabel^  toolStripStatusLabel1;
    	private: System::Windows::Forms::Label^  label10;
    	private: System::Net::WebClient^ Client;
    
    	private:
    		/// <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)
    		{
    			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
    			this->Client = (gcnew System::Net::WebClient());
    			this->panel1 = (gcnew System::Windows::Forms::Panel());
    			this->btn_Min = (gcnew System::Windows::Forms::Button());
    			this->btn_Exit = (gcnew System::Windows::Forms::Button());
    			this->groupBox1 = (gcnew System::Windows::Forms::GroupBox());
    			this->panel2 = (gcnew System::Windows::Forms::Panel());
    			this->btn_Start = (gcnew System::Windows::Forms::Button());
    			this->tb_Pfad = (gcnew System::Windows::Forms::TextBox());
    			this->label1 = (gcnew System::Windows::Forms::Label());
    			this->groupBox2 = (gcnew System::Windows::Forms::GroupBox());
    			this->panel3 = (gcnew System::Windows::Forms::Panel());
    			this->btn_Add = (gcnew System::Windows::Forms::Button());
    			this->tb_Dateiname = (gcnew System::Windows::Forms::TextBox());
    			this->label2 = (gcnew System::Windows::Forms::Label());
    			this->tb_Url = (gcnew System::Windows::Forms::TextBox());
    			this->label3 = (gcnew System::Windows::Forms::Label());
    			this->lb_Files = (gcnew System::Windows::Forms::ListBox());
    			this->groupBox3 = (gcnew System::Windows::Forms::GroupBox());
    			this->panel5 = (gcnew System::Windows::Forms::Panel());
    			this->lbl_T_Downloaded = (gcnew System::Windows::Forms::Label());
    			this->lbl_T_Übertragen = (gcnew System::Windows::Forms::Label());
    			this->label5 = (gcnew System::Windows::Forms::Label());
    			this->panel4 = (gcnew System::Windows::Forms::Panel());
    			this->lbl_C_Gesammt = (gcnew System::Windows::Forms::Label());
    			this->lbl_C_Übertragen = (gcnew System::Windows::Forms::Label());
    			this->label4 = (gcnew System::Windows::Forms::Label());
    			this->PB_Current = (gcnew System::Windows::Forms::ProgressBar());
    			this->statusStrip1 = (gcnew System::Windows::Forms::StatusStrip());
    			this->toolStripStatusLabel1 = (gcnew System::Windows::Forms::ToolStripStatusLabel());
    			this->label10 = (gcnew System::Windows::Forms::Label());
    			this->label6 = (gcnew System::Windows::Forms::Label());
    			this->label7 = (gcnew System::Windows::Forms::Label());
    			this->panel1->SuspendLayout();
    			this->groupBox1->SuspendLayout();
    			this->panel2->SuspendLayout();
    			this->groupBox2->SuspendLayout();
    			this->panel3->SuspendLayout();
    			this->groupBox3->SuspendLayout();
    			this->panel5->SuspendLayout();
    			this->panel4->SuspendLayout();
    			this->statusStrip1->SuspendLayout();
    			this->SuspendLayout();
    			// 
    			// Client
    			// 
    			this->Client->BaseAddress = L"";
    			this->Client->CachePolicy = nullptr;
    			this->Client->Credentials = nullptr;
    			this->Client->Encoding = (cli::safe_cast<System::Text::Encoding^  >(resources->GetObject(L"Client.Encoding")));
    			this->Client->Headers = (cli::safe_cast<System::Net::WebHeaderCollection^  >(resources->GetObject(L"Client.Headers")));
    			this->Client->QueryString = (cli::safe_cast<System::Collections::Specialized::NameValueCollection^  >(resources->GetObject(L"Client.QueryString")));
    			this->Client->UseDefaultCredentials = false;
    			this->Client->DownloadFileCompleted += gcnew System::ComponentModel::AsyncCompletedEventHandler(this, &Form1::Client_DownloadFileCompleted);
    			this->Client->DownloadProgressChanged += gcnew System::Net::DownloadProgressChangedEventHandler(this, &Form1::Client_DownloadProgressChanged);
    			// 
    			// panel1
    			// 
    			this->panel1->Controls->Add(this->btn_Min);
    			this->panel1->Controls->Add(this->btn_Exit);
    			this->panel1->Location = System::Drawing::Point(0, 0);
    			this->panel1->Name = L"panel1";
    			this->panel1->Size = System::Drawing::Size(700, 40);
    			this->panel1->TabIndex = 0;
    			// 
    			// btn_Min
    			// 
    			this->btn_Min->Location = System::Drawing::Point(582, 8);
    			this->btn_Min->Name = L"btn_Min";
    			this->btn_Min->Size = System::Drawing::Size(50, 20);
    			this->btn_Min->TabIndex = 2;
    			this->btn_Min->UseVisualStyleBackColor = true;
    			// 
    			// btn_Exit
    			// 
    			this->btn_Exit->Location = System::Drawing::Point(638, 8);
    			this->btn_Exit->Name = L"btn_Exit";
    			this->btn_Exit->Size = System::Drawing::Size(50, 20);
    			this->btn_Exit->TabIndex = 1;
    			this->btn_Exit->UseVisualStyleBackColor = true;
    			// 
    			// groupBox1
    			// 
    			this->groupBox1->Controls->Add(this->panel2);
    			this->groupBox1->Location = System::Drawing::Point(477, 46);
    			this->groupBox1->Name = L"groupBox1";
    			this->groupBox1->Size = System::Drawing::Size(211, 196);
    			this->groupBox1->TabIndex = 1;
    			this->groupBox1->TabStop = false;
    			// 
    			// panel2
    			// 
    			this->panel2->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->panel2->Controls->Add(this->btn_Start);
    			this->panel2->Controls->Add(this->tb_Pfad);
    			this->panel2->Controls->Add(this->label1);
    			this->panel2->Location = System::Drawing::Point(6, 19);
    			this->panel2->Name = L"panel2";
    			this->panel2->Size = System::Drawing::Size(199, 171);
    			this->panel2->TabIndex = 3;
    			// 
    			// btn_Start
    			// 
    			this->btn_Start->BackColor = System::Drawing::SystemColors::ButtonFace;
    			this->btn_Start->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
    			this->btn_Start->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->btn_Start->Location = System::Drawing::Point(3, 140);
    			this->btn_Start->Name = L"btn_Start";
    			this->btn_Start->Size = System::Drawing::Size(193, 28);
    			this->btn_Start->TabIndex = 4;
    			this->btn_Start->Text = L"Download starten";
    			this->btn_Start->UseVisualStyleBackColor = false;
    			this->btn_Start->Click += gcnew System::EventHandler(this, &Form1::Start);
    			// 
    			// tb_Pfad
    			// 
    			this->tb_Pfad->Location = System::Drawing::Point(3, 41);
    			this->tb_Pfad->Name = L"tb_Pfad";
    			this->tb_Pfad->Size = System::Drawing::Size(193, 20);
    			this->tb_Pfad->TabIndex = 3;
    			// 
    			// label1
    			// 
    			this->label1->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label1->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label1->Location = System::Drawing::Point(3, 15);
    			this->label1->Name = L"label1";
    			this->label1->Size = System::Drawing::Size(193, 23);
    			this->label1->TabIndex = 3;
    			this->label1->Text = L"DownloadPfad :";
    			this->label1->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// groupBox2
    			// 
    			this->groupBox2->Controls->Add(this->panel3);
    			this->groupBox2->Location = System::Drawing::Point(12, 46);
    			this->groupBox2->Name = L"groupBox2";
    			this->groupBox2->Size = System::Drawing::Size(211, 196);
    			this->groupBox2->TabIndex = 2;
    			this->groupBox2->TabStop = false;
    			// 
    			// panel3
    			// 
    			this->panel3->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->panel3->Controls->Add(this->btn_Add);
    			this->panel3->Controls->Add(this->tb_Dateiname);
    			this->panel3->Controls->Add(this->label2);
    			this->panel3->Controls->Add(this->tb_Url);
    			this->panel3->Controls->Add(this->label3);
    			this->panel3->Location = System::Drawing::Point(6, 19);
    			this->panel3->Name = L"panel3";
    			this->panel3->Size = System::Drawing::Size(199, 171);
    			this->panel3->TabIndex = 3;
    			// 
    			// btn_Add
    			// 
    			this->btn_Add->BackColor = System::Drawing::SystemColors::ButtonFace;
    			this->btn_Add->FlatStyle = System::Windows::Forms::FlatStyle::Popup;
    			this->btn_Add->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->btn_Add->Location = System::Drawing::Point(3, 140);
    			this->btn_Add->Name = L"btn_Add";
    			this->btn_Add->Size = System::Drawing::Size(193, 28);
    			this->btn_Add->TabIndex = 3;
    			this->btn_Add->Text = L"Hinzufügen  -->";
    			this->btn_Add->UseVisualStyleBackColor = false;
    			this->btn_Add->Click += gcnew System::EventHandler(this, &Form1::Hinzufügen);
    			// 
    			// tb_Dateiname
    			// 
    			this->tb_Dateiname->Location = System::Drawing::Point(3, 99);
    			this->tb_Dateiname->Name = L"tb_Dateiname";
    			this->tb_Dateiname->Size = System::Drawing::Size(193, 20);
    			this->tb_Dateiname->TabIndex = 5;
    			// 
    			// label2
    			// 
    			this->label2->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label2->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label2->Location = System::Drawing::Point(3, 73);
    			this->label2->Name = L"label2";
    			this->label2->Size = System::Drawing::Size(193, 23);
    			this->label2->TabIndex = 5;
    			this->label2->Text = L"Dateiname + Endung :";
    			this->label2->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// tb_Url
    			// 
    			this->tb_Url->Location = System::Drawing::Point(3, 41);
    			this->tb_Url->Name = L"tb_Url";
    			this->tb_Url->Size = System::Drawing::Size(193, 20);
    			this->tb_Url->TabIndex = 4;
    			// 
    			// label3
    			// 
    			this->label3->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label3->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label3->Location = System::Drawing::Point(3, 15);
    			this->label3->Name = L"label3";
    			this->label3->Size = System::Drawing::Size(193, 23);
    			this->label3->TabIndex = 4;
    			this->label3->Text = L"Url :";
    			this->label3->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// lb_Files
    			// 
    			this->lb_Files->FormattingEnabled = true;
    			this->lb_Files->Location = System::Drawing::Point(229, 53);
    			this->lb_Files->Name = L"lb_Files";
    			this->lb_Files->Size = System::Drawing::Size(242, 186);
    			this->lb_Files->TabIndex = 3;
    			// 
    			// groupBox3
    			// 
    			this->groupBox3->Controls->Add(this->panel5);
    			this->groupBox3->Controls->Add(this->panel4);
    			this->groupBox3->Location = System::Drawing::Point(12, 275);
    			this->groupBox3->Name = L"groupBox3";
    			this->groupBox3->Size = System::Drawing::Size(676, 121);
    			this->groupBox3->TabIndex = 4;
    			this->groupBox3->TabStop = false;
    			this->groupBox3->Text = L"Status";
    			// 
    			// panel5
    			// 
    			this->panel5->Controls->Add(this->lbl_T_Downloaded);
    			this->panel5->Controls->Add(this->lbl_T_Übertragen);
    			this->panel5->Controls->Add(this->label5);
    			this->panel5->Location = System::Drawing::Point(350, 19);
    			this->panel5->Name = L"panel5";
    			this->panel5->Size = System::Drawing::Size(320, 96);
    			this->panel5->TabIndex = 5;
    			// 
    			// lbl_T_Downloaded
    			// 
    			this->lbl_T_Downloaded->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->lbl_T_Downloaded->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->lbl_T_Downloaded->Location = System::Drawing::Point(0, 64);
    			this->lbl_T_Downloaded->Name = L"lbl_T_Downloaded";
    			this->lbl_T_Downloaded->Size = System::Drawing::Size(320, 23);
    			this->lbl_T_Downloaded->TabIndex = 8;
    			this->lbl_T_Downloaded->Text = L"0 von 0 Dateien gedownloaded";
    			this->lbl_T_Downloaded->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// lbl_T_Übertragen
    			// 
    			this->lbl_T_Übertragen->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->lbl_T_Übertragen->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->lbl_T_Übertragen->Location = System::Drawing::Point(0, 32);
    			this->lbl_T_Übertragen->Name = L"lbl_T_Übertragen";
    			this->lbl_T_Übertragen->Size = System::Drawing::Size(188, 23);
    			this->lbl_T_Übertragen->TabIndex = 7;
    			this->lbl_T_Übertragen->Text = L"Übertragene Mbytes: ";
    			this->lbl_T_Übertragen->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
    			// 
    			// label5
    			// 
    			this->label5->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label5->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label5->Location = System::Drawing::Point(0, 0);
    			this->label5->Name = L"label5";
    			this->label5->Size = System::Drawing::Size(320, 23);
    			this->label5->TabIndex = 6;
    			this->label5->Text = L"Total :";
    			this->label5->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// panel4
    			// 
    			this->panel4->Controls->Add(this->label7);
    			this->panel4->Controls->Add(this->label6);
    			this->panel4->Controls->Add(this->lbl_C_Gesammt);
    			this->panel4->Controls->Add(this->lbl_C_Übertragen);
    			this->panel4->Controls->Add(this->label4);
    			this->panel4->Location = System::Drawing::Point(6, 19);
    			this->panel4->Name = L"panel4";
    			this->panel4->Size = System::Drawing::Size(320, 96);
    			this->panel4->TabIndex = 0;
    			// 
    			// lbl_C_Gesammt
    			// 
    			this->lbl_C_Gesammt->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->lbl_C_Gesammt->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->lbl_C_Gesammt->Location = System::Drawing::Point(-1, 64);
    			this->lbl_C_Gesammt->Name = L"lbl_C_Gesammt";
    			this->lbl_C_Gesammt->Size = System::Drawing::Size(197, 23);
    			this->lbl_C_Gesammt->TabIndex = 7;
    			this->lbl_C_Gesammt->Text = L"Mbytes insgesammt: ";
    			this->lbl_C_Gesammt->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
    			// 
    			// lbl_C_Übertragen
    			// 
    			this->lbl_C_Übertragen->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->lbl_C_Übertragen->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->lbl_C_Übertragen->Location = System::Drawing::Point(-1, 32);
    			this->lbl_C_Übertragen->Name = L"lbl_C_Übertragen";
    			this->lbl_C_Übertragen->Size = System::Drawing::Size(197, 23);
    			this->lbl_C_Übertragen->TabIndex = 6;
    			this->lbl_C_Übertragen->Text = L"Übertragene Mbytes: ";
    			this->lbl_C_Übertragen->TextAlign = System::Drawing::ContentAlignment::MiddleLeft;
    			// 
    			// label4
    			// 
    			this->label4->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label4->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label4->Location = System::Drawing::Point(0, 0);
    			this->label4->Name = L"label4";
    			this->label4->Size = System::Drawing::Size(320, 23);
    			this->label4->TabIndex = 5;
    			this->label4->Text = L"Current :";
    			this->label4->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// PB_Current
    			// 
    			this->PB_Current->Location = System::Drawing::Point(12, 434);
    			this->PB_Current->Name = L"PB_Current";
    			this->PB_Current->Size = System::Drawing::Size(676, 29);
    			this->PB_Current->TabIndex = 7;
    			// 
    			// statusStrip1
    			// 
    			this->statusStrip1->Items->AddRange(gcnew cli::array< System::Windows::Forms::ToolStripItem^  >(1) {this->toolStripStatusLabel1});
    			this->statusStrip1->Location = System::Drawing::Point(0, 478);
    			this->statusStrip1->Name = L"statusStrip1";
    			this->statusStrip1->RenderMode = System::Windows::Forms::ToolStripRenderMode::Professional;
    			this->statusStrip1->Size = System::Drawing::Size(700, 22);
    			this->statusStrip1->SizingGrip = false;
    			this->statusStrip1->TabIndex = 8;
    			this->statusStrip1->Text = L"statusStrip1";
    			// 
    			// toolStripStatusLabel1
    			// 
    			this->toolStripStatusLabel1->Font = (gcnew System::Drawing::Font(L"Segoe UI", 9.75F, System::Drawing::FontStyle::Bold, System::Drawing::GraphicsUnit::Point, 
    				static_cast<System::Byte>(0)));
    			this->toolStripStatusLabel1->Name = L"toolStripStatusLabel1";
    			this->toolStripStatusLabel1->Size = System::Drawing::Size(53, 17);
    			this->toolStripStatusLabel1->Text = L"Speed: ";
    			// 
    			// label10
    			// 
    			this->label10->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label10->BorderStyle = System::Windows::Forms::BorderStyle::Fixed3D;
    			this->label10->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label10->Location = System::Drawing::Point(12, 408);
    			this->label10->Name = L"label10";
    			this->label10->Size = System::Drawing::Size(676, 23);
    			this->label10->TabIndex = 9;
    			this->label10->Text = L"Aktuelle Datei:";
    			this->label10->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// label6
    			// 
    			this->label6->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label6->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label6->Location = System::Drawing::Point(193, 32);
    			this->label6->Name = L"label6";
    			this->label6->Size = System::Drawing::Size(127, 23);
    			this->label6->TabIndex = 8;
    			this->label6->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// label7
    			// 
    			this->label7->BackColor = System::Drawing::SystemColors::ActiveCaption;
    			this->label7->Font = (gcnew System::Drawing::Font(L"Microsoft Sans Serif", 12, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
    				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
    			this->label7->Location = System::Drawing::Point(193, 64);
    			this->label7->Name = L"label7";
    			this->label7->Size = System::Drawing::Size(127, 23);
    			this->label7->TabIndex = 9;
    			this->label7->TextAlign = System::Drawing::ContentAlignment::MiddleCenter;
    			// 
    			// Form1
    			// 
    			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
    			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
    			this->ClientSize = System::Drawing::Size(700, 500);
    			this->ControlBox = false;
    			this->Controls->Add(this->label10);
    			this->Controls->Add(this->statusStrip1);
    			this->Controls->Add(this->PB_Current);
    			this->Controls->Add(this->groupBox3);
    			this->Controls->Add(this->lb_Files);
    			this->Controls->Add(this->groupBox2);
    			this->Controls->Add(this->groupBox1);
    			this->Controls->Add(this->panel1);
    			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::None;
    			this->MaximizeBox = false;
    			this->MinimizeBox = false;
    			this->Name = L"Form1";
    			this->ShowIcon = false;
    			this->ShowInTaskbar = false;
    			this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
    			this->panel1->ResumeLayout(false);
    			this->groupBox1->ResumeLayout(false);
    			this->panel2->ResumeLayout(false);
    			this->panel2->PerformLayout();
    			this->groupBox2->ResumeLayout(false);
    			this->panel3->ResumeLayout(false);
    			this->panel3->PerformLayout();
    			this->groupBox3->ResumeLayout(false);
    			this->panel5->ResumeLayout(false);
    			this->panel4->ResumeLayout(false);
    			this->statusStrip1->ResumeLayout(false);
    			this->statusStrip1->PerformLayout();
    			this->ResumeLayout(false);
    			this->PerformLayout();
    
    		}
    #pragma endregion
    	private: void Hinzufügen(System::Object^  sender, System::EventArgs^  e)
    			 {
    				 if ((tb_Url->TextLength > 0) && (tb_Dateiname->TextLength > 0))
    				 {
    
    						 String^ Name = tb_Dateiname->Text->ToString();
    						 String^ Url = tb_Url->Text->ToString();
    						 int ExistResult = lb_Files->Items->IndexOf(Name->ToString()->ToString());
    						 if (ExistResult == -1)
    						 {
    							 Container1->Add(Name,Url);
    							 lb_Files->Items->Add(Name);
    
    							 Name = nullptr;
    							 Url = nullptr;
    
    							 tb_Dateiname->Clear();
    							 tb_Url->Clear();
    						 }
    						 else
    						 {
    							 Name = nullptr;
    							 Url = nullptr;
    
    							 tb_Dateiname->Clear();
    							 tb_Url->Clear();
    							 MessageBox::Show("Dateiname schon vergeben !","Fehler",MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
    						 }
    				 }
    				 else
    				 {
    					 MessageBox::Show("Es müssen alle Felder ausgefüllt sein !","Fehler",MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
    				 }
    			 }
    
    private: void Start(System::Object^  sender, System::EventArgs^  e) 
    		 {
    			 if (tb_Pfad->TextLength > 0)
    			 {
    				 IO::DirectoryInfo^ Temp = gcnew IO::DirectoryInfo(tb_Pfad->Text->ToString());
    				 if (Temp->Exists)
    				 {
    					 btn_Start->Enabled = false;
    			         btn_Add->Enabled = false;
    					 Pfad = tb_Pfad->Text->ToString();
    					 Counter_max = lb_Files->Items->Count - 1;
    					 System::Threading::Thread ^T1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1::Do));
    				     T1->Start();     
    				 }
    				 else
    				 {
    					 MessageBox::Show("Verzeichnis existiert nicht !","Fehler",MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
    				 }
    			 }
    			 else
    			 {
    				 MessageBox::Show("Es wurde kein Pfad angegeben !","Fehler",MessageBoxButtons::OK,MessageBoxIcon::Exclamation);
    			 }
    
    		 }
    
    		 private: delegate void DoDelegate();
    
    private: void Do()
    			{
                 if (!InvokeRequired)
                 {
    				String^ Key = lb_Files->Items[Counter]->ToString();
    				String^ cUrl = Container1[Key]->ToString();
    				System::Uri ^Url = gcnew System::Uri(cUrl,UriKind::RelativeOrAbsolute);
    				Client->DownloadFileAsync(Url,Pfad + Key);
    			 }
                 else
                 {
    				 Invoke(gcnew DoDelegate(this, &Form1::Do));
                 }
             } 
    
    private: void Client_DownloadFileCompleted(System::Object^  sender, System::ComponentModel::AsyncCompletedEventArgs^  e) 
    		 {
    			 if (Counter == Counter_max)
    			 {
    				 Ende();
    			 }
    			 else
    			 {
    				 Counter += 1;
    				 System::Threading::Thread::Sleep(500);
    				 Do();
    			 }
    
    		 }
    
    private: void Client_DownloadProgressChanged(System::Object^  sender, System::Net::DownloadProgressChangedEventArgs^  e) 
    		 {
    			 label6->Text = e->BytesReceived.ToString();
    			 label7->Text = e->TotalBytesToReceive.ToString();
    			 PB_Current->Value = e->ProgressPercentage;
    		 }
    
    		 private: void Ende()
    			{
    				MessageBox::Show("Ende");
    			}
    
    };
    }
    


  • PeterFragt schrieb:

    Hallo,

    eine weiter Möglichkeit (nicht unbedingt ratsam) den Fehler

    Threadübergreifender Zugriff auf Steuerelement

    wegzubekommen, ist z.B. im Konstruktor der Form1 folgendes hinzuzufügen:

    Form1::CheckForIllegalCrossThreadCalls=false;
    

    Nein, dass ist keine Möglichkeit. Es ist Symptombekämpfung, mit dem Resultat, dass deine Appl. ein falsches oder unvorhersehbares Verhalten an den Tag legt.

    Jetzt aber zu meiner Frage:
    Ich hab das Beispiel eben auch mal ausprobiert (1:1 übernommen) und hatte eigentlich erwartet, dass das Fenster (also die Form1) nicht blockiert!
    Deswegen bette ich die Methode Do() ja in einen eigenen Thread, oder nicht?
    Bei mir blockiert das Fenster trotzdem, bis mein Testzähler durchgelaufen ist.

    rufe ich die Methode Do() so auf:

    ...
    	private: 
    		System::Void btn_Click(System::Object^  sender, System::EventArgs^  e)
    		{
    			System::Diagnostics::Debug::WriteLine("CLICK");
    			Do();
    		}
    
    		delegate void DoDelegate(); 
    
    		void Do()
    		{			
    				int i=0;
                    while(i<200)
    				{
    					System::Diagnostics::Debug::Write("Do it ");
    					System::Diagnostics::Debug::WriteLine(i);
    					i++;
    				}
    		}
    	};// end class Form1
    
    } // end namespace
    

    verhält sie sich bei mir exakt so wie das obige Beispiel 😕

    Du hast ja auch keinen separaten Thread. Logisch blockiert da das UI.
    Simon



  • Du hast ja auch keinen separaten Thread. Logisch blockiert da das UI.

    In dem Beispiel nicht, aber in dem vorherigen für C++-Learner. Das sollte nur demonstrieren, dass es sich so genauso verhält wie das hier:

    private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e)
             {
                 System::Threading::Thread^ T1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1::Do));
                 T1->Start();
             }
    
    private: delegate void DoDelegate();
    
    private: void Do()
             {
                 if (!InvokeRequired)
                 {
                    progressBar1->Value = 50;
                 }
                 else
                 {
                     Invoke(gcnew DoDelegate(this, &Form1::Do));
                 }
             }
    };
    


  • private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) 
             { 
                 System::Threading::Thread^ T1 = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this,&Form1:clown:); 
                 T1->Start(); 
             } 
    
    private: delegate void DoDelegate(); 
    
    private: void Do() 
             { 
                 if (!InvokeRequired) 
                 {
                    // Läuft auf UI Thread, blockiert also dein UI.
                    // Hier ist der Platz um dein UI zu aktualisieren.
                    progressBar1->Value = 50; 
                 } 
                 else 
                 { 
                    // Läuft auf dem erstellten, separaten Thread.
                    // Hier ist der Platz für deinen Langandauernden Dinge.
                     Invoke(gcnew DoDelegate(this, &Form1:clown:); 
                 } 
             } 
    };
    

    Ev. helfen die Kommentare im Code.
    Simon



  • Ev. helfen die Kommentare im Code.
    Simon

    Danke Simon! Jetzt läuft es zumindest mal 🙂

    Leider wirft das bei mir gleich mal weitere Fragen auf, mit denen ich dich (oder jmd anderen) gleich mal nerven werde 😃

    Kann ich das so sagen, dass hier immer erst der ELSE-Block aufgerufen wird für nicht blockierende Aktionen, quasi-parallele Aktionen und dann der Aufruf

    Invoke(gcnew DoDelegate(this, &Form1::Do));
    

    den blockierenden Teil aufruft?
    Ist der Anweisungsblock

    if(!InvokeRequired){ ..}
    

    sozusagen der vom OS synchronisierte Teil (durch Blockierung)? Oder sind jetzt beide Teile synchronisiert, falls ich konkurrierende Aufrufe durchführe?

    theta schrieb:

    PeterFragt schrieb:

    Hallo,

    eine weiter Möglichkeit (nicht unbedingt ratsam) den Fehler

    Threadübergreifender Zugriff auf Steuerelement

    wegzubekommen, ist z.B. im Konstruktor der Form1 folgendes hinzuzufügen:

    Form1::CheckForIllegalCrossThreadCalls=false;
    

    Nein, dass ist keine Möglichkeit. Es ist Symptombekämpfung, mit dem Resultat, dass deine Appl. ein falsches oder unvorhersehbares Verhalten an den Tag legt.

    Muss ich mir hier als Programmierer nicht einfach nur dafür selbst sorgen, dass mögliche parallele Zugriffe keine Inkonsistenzen auslösen, oder geht es um Systemstabilität? Z.B. Bei einer Stoppuhr könnte es ja gar nicht zu Konflikten kommen, oder seh ich das falsch?

    Gruß



  • Muss ich mir hier als Programmierer nicht einfach nur dafür selbst sorgen, dass mögliche parallele Zugriffe keine Inkonsistenzen auslösen, oder geht es um Systemstabilität? Z.B. Bei einer Stoppuhr könnte es ja gar nicht zu Konflikten kommen, oder seh ich das falsch?

    Das siehst Du falsch. Unter Windows sind die Fenster Thread Affin. D.h. sie gehören zu einem bestimmten Thread. Zugriffe von anderen Thread sind nicht erlaubt, führen zu unvorhersagbaren oder unerwünschtem Verhalten.

    Edit:

    Kann ich das so sagen, dass hier immer erst der ELSE-Block aufgerufen wird für nicht blockierende Aktionen, quasi-parallele Aktionen und dann der Aufruf

    Invoke(gcnew DoDelegate(this, &Form1:clown:);
    

    den blockierenden Teil aufruft?

    Hmm.. auf dem UI Thread wird halt das UI blockiert und auf dem anderen Thread wird halt der andere Thread blockiert, falls Du was blockierendes tust.

    Ist der Anweisungsblock

    if(!InvokeRequired){ ..}
    

    sozusagen der vom OS synchronisierte Teil (durch Blockierung)? Oder sind jetzt beide Teile synchronisiert, falls ich konkurrierende Aufrufe durchführe?

    Hmm... InvokeRequired fragt ab ob Synchronisation (hier dadurch, dass ein Aufruf auf einen anderen Thread gemarshallt wird) nötig ist und Invoke führt eben dieses Marshalling des Aufrufes durch.

    Simon



  • Leider kriege ich das Gewünschte immer noch nicht hin.

    Ich baue einen Timer, der eine Anzahl von Sekunden herunterzählen kann und eine Oberfläche die das in Minuten und Sekunden (in Labels) anzeigt und dabei eine Progressbar abbaut. Das Update funktioniert im Sekundentakt.
    Der Timer macht eig. nichts anderes, als jede Sekunde per delegate eine Methode der Form1 aufzurufen

    Form1::updateClock(int, int)
    

    Im Timer

    static gcroot <DelUpdate^> update;
    ...
    update->Invoke(min, sec);
    

    Ich Naivling hatte jetzt gehofft, dass das folgendermaßen funzt 🙂

    void Do()
    		{			
    			if(!InvokeRequired)
    			{// Blockiert
    				timer->StartTimer();
    			}
    			else
    			{// Blockiert nicht
    				Invoke(gcnew DoDelegate(this, &Form1::Do));
    			} 
    		}
    

    Der Timer läuft und nur die Progressbar funktioniert ordnungsgemäß, Form1 blockiert, so dass die aktuellen Minuten und Sekunden in den Labels nicht aktualisiert werden und das Fenster auch nicht beweglich ist.

    In den else-Block von

    if(!InvokeRequired)
    

    löst der Aufruf von StartTimer() ja den allseits bekannten Fehler aus. Was mache ich falsch oder was weiß ich noch nicht?


Anmelden zum Antworten