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::MyThread::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-[...]hreadstart%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, botów: 0