Przekazywanie parametrów do funkcji ThreadStart

0

Witam, jestem w trakcie pisania programu obsługującego wielowątkowość. W konstruktorze mojej klasy tworzącej wątki aktualnie tworzę je na sztywno (poniżej kod z funkcją), ale chciałbym, żeby to jakoś po ludzku wyglądało i było elastyczne, zrobić to na pętli (stworzona poniżej pod wątkami na sztywno). Niestety problem jest taki, że w konstruktorze ThreadStart

ThreadStart(this, &ThreadNamespace::MyThread::Edit1)

podaję referencję do funkcji (tutaj też na sztywno) i to działa. Natomiast jak zrobię w ten sposób ThreadStart(this, &ThreadNamespace::EditWithTimer(i))

, czyli referencja funkcji z parametrem to już niestety jest błąd kompilacji "Expression must be an lvalue or a function designator". Pytanie moje brzmi: jak przekazać referencje do funkcji z parametrem, bądź zrobić to tak, aby zadziałało zgodnie z moim zamysłem?

Konstruktor klasy z wątkami
```cpp
ThreadNamespace::MyThread::MyThread(int Aneg, wchar_t* Aplik, wchar_t* Aplik_wy, FileHeader* Abitmap, int ThreadAmountChosenByUser)
{
	//processorNumber = Environment::ProcessorCount;
	// Ustawienie wartości parametrów
	neg = Aneg;
	InputFile = Aplik;
	OutputFile = Aplik_wy;
	bitmap = Abitmap;
	processorNumber = ThreadAmountChosenByUser;

	/* Utworzenie nowych wątkow */
	if (processorNumber == 1)
	{
		Thread1 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit1));
	}
	else if (processorNumber == 2)
	{
		//Thread1 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit1));
		//Thread2 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit2));

		//Thread1 = gcnew Thread(gcnew ThreadStart());
		//Thread2 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit2));
	}
	else if (processorNumber == 4)
	{
		Thread1 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit1));
		Thread2 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit2));
		Thread3 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit3));
		Thread4 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit4));
	}
	else if (processorNumber == 8)
	{
		Thread1 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit1));
		Thread2 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit2));
		Thread3 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit3));
		Thread4 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit4));
		Thread5 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit5));
		Thread6 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit6));
		Thread7 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit7));
		Thread8 = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::Edit8));
	}

        //nowa wersja
	for (int i = 0; i < processorNumber; i++)
	{
		int temp = i + 1;
		Threads[i] = gcnew Thread(gcnew ThreadStart(this, &ThreadNamespace::MyThread::EditWithTimer(i)));
	}
}

Funkcja z parametrem

void ThreadNamespace::MyThread::EditWithTimer(int threadNumber)
{
	if (threadNumber == 1)
	{
		TimeTab[threadNumber - 1] = Edit(true, threadNumber);
	}
	else
	{
		TimeTab[threadNumber - 1] = Edit(false, threadNumber);
	}
}
2

Jeżeli potrzebujesz parametrów w ThreadStart, użyj ParametrizedThreadStart.

Thread t = new Thread (new ParameterizedThreadStart(funkcja));
t.Start(parametr);

Gdzie parametr jest typu object zgodnie z delegatem, więc musisz sobie go zrzutować na odpowiedni typ już wewnątrz wątku.

http://msdn.microsoft.com/pl-pl/library/system.threading.parameterizedthreadstart%28v=vs.110%29.aspx

0

Nie do końca to jest to o co mi chodziło. Potrzebuję przekazać jako argument ThreadStart referencję do funkcji, do której także przesyłam parametr.

1

Funkcja to jest DoSomething(). DoSomething(object) to nie jest już funkcja, tylko jej wywołanie, więc nie da się jej wykorzystać jako delegata (wskaźnika na funkcję).

Nadal nie widzę problemu z wykorzystaniem ParametrizedThreadStart. Przecież nadal te wątki musisz gdzieś uruchamiać - dlatego przekazuj parametr w uruchamianiu.
Sorry za C#, ale nie znam C++/CLI:

Thread[] t = new Thread[processorNumber];
for (int i = 0; i < processorNumber; i++)
{
    t[i] = new Thread(new ParametrizedThreadStart(ThreadNamespace::MyThread::EditWithTimer);    
}

// kiedy potrzeba
for (int i = 0; i < processorNumber; i++)
    t[i].Start(i);


// plus:
void EditWithTimer(object o)
{
    int threadNumber = (int)o;
    // a potem już jak masz
}
1

powyższy kod w składni C++/CLI (nie sprawdzany)

cli::array<Thread^> ^t = gcnew cli::array<Thread^>(processorNumber);
for (int i = 0; i < processorNumber; i++)
{
    t[i] = gcnew Thread(gcnew ParametrizedThreadStart(&ThreadNamespace::MyThread::EditWithTimer));
}
 
// kiedy potrzeba
for (int i = 0; i < processorNumber; i++)
    t[i]->Start(i);
 
 
// plus:
void EditWithTimer(Object ^o)
{
    int threadNumber = safe_cast<int>(o);
    // a potem już jak masz
}
0

Teraz rozumiem, wybaczcie za wprowadzenie w błąd. To pierwszy raz gdy używam wątków. Dziękuję za pomoc.

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