Visyal Studio 2010 - Threads

0

Witam mam problem, wywołując funkcje "Funkcja()" przez wątek nie mam dostępu do edytowania np. przycisków progressbaru itp.

 
void Funkcja()
 {
      this->button1->Text = L"Start";
 }

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) 
{
				 
	   Form1^ w = gcnew Form1;
	   Thread^ NewThread = gcnew Thread ( gcnew ThreadStart(w, &Form1::Funkcja));
	   NewThread->Start();
}

Program skompiluje sie normalnie jednak Nazwa przycisku nie zmieni sie na "Start"
Dlaczego?

0

Wszystkie zmiany w GUI muszą być robione w wątku do tego przeznaczonym. Poczytaj o InvokeRequired i Invoke.

0

A nie da sie jakoś tego zrobić przez parametry?

0

Czyli co mam to zrobić w ten sposób?

 MyFormControl::MyFormControl()
{
   myButton = gcnew Button;
   myListBox = gcnew ListBox;
   myButton->Location = Point(72,160);
   myButton->Size = System::Drawing::Size( 152, 32 );
   myButton->TabIndex = 1;
   myButton->Text = "Add items in list box";
   myButton->Click += gcnew EventHandler( this, &MyFormControl::Button_Click );
   myListBox->Location = Point(48,32);
   myListBox->Name = "myListBox";
   myListBox->Size = System::Drawing::Size( 200, 95 );
   myListBox->TabIndex = 2;
   ClientSize = System::Drawing::Size( 292, 273 );
   array<Control^>^formControls = {myListBox,myButton};
   Controls->AddRange( formControls );
   Text = " 'Control_Invoke' example ";
   myDelegate = gcnew AddListItem( this, &MyFormControl::AddListItemMethod );
}

void MyFormControl::AddListItemMethod( String^ myString )
{
   myListBox->Items->Add( myString );
}

void MyFormControl::Button_Click( Object^ /*sender*/, EventArgs^ /*e*/ )
{
   myThread = gcnew Thread( gcnew ThreadStart( this, &MyFormControl::ThreadFunction ) );
   myThread->Start();
}

void MyFormControl::ThreadFunction()
{
   MyThreadClass^ myThreadClassObject = gcnew MyThreadClass( this );
   myThreadClassObject->Run();
}
0

To, w jakim wątku został stworzony obiekt nie ma w tym wypadku dla metod jej klasy znaczenia. Wciąż musisz użyć Invoke (i InvokeRequired), jeżeli chcesz z innego wątku zmodyfikować UI.

0
		void Funkcja()
		{
			if (InvokeRequired)
				Invoke(gcnew ThreadStart(this, &Form1::Funkcja));
			else
			{
				this->button1->Text = L"Start";
			}
		}
		 
		private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) 
		{
			Thread^ NewThread = gcnew Thread (gcnew ThreadStart(this, &Form1::Funkcja));
			NewThread->Start();
		}
0

Wielkie dzięki ;-)

0

a dlaczego jak odpalę coś w drugim wątku to eventy w oknie głównym sa zablokowane do wykonania się wątku?
np:

                void Funkcja()
                {
                        if (InvokeRequired)
                                Invoke(gcnew ThreadStart(this, &Form1::Funkcja));
                        else
                        {
                                Sleep(10000); // 10 sec
                        }
                }
 
                private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) 
                {
                        Thread^ NewThread = gcnew Thread (gcnew ThreadStart(this, &Form1::Funkcja));
                        NewThread->Start();
                }
 

W tym wypadku okno główne będzie zablokowane na 10 sec dlaczego?

0

Pod Invoke umieszcza się tylko odwołania do formy. Sleep musi być poza.

                void Funkcja2()
                {
                        this->button1->Text = L"Start";
                }

                void Funkcja()
                {
                        Sleep(10000); // 10 sec

                        if (InvokeRequired)
                                Invoke(gcnew ThreadStart(this, &Form1::Funkcja2));
                        else
                                Funkcja2();
                }

albo

                void Funkcja2()
                {
                        if (InvokeRequired)
                                Invoke(gcnew ThreadStart(this, &Form1::Funkcja2));
                        else
                                this->button1->Text = L"Start";
                }

                void Funkcja()
                {
                        Sleep(10000); // 10 sec
                        Funkcja2();
                }

W skrócie: Invoke wywołuje funkcję w oryginalnym wątku interfejsu użytkownka. Dlatego twój sleep blokuje okno.

0

ok już rozumiem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1