Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[C++/CLI, Visual Studio 2012] Problem z wątkami z biblioteki System::Thread

Ostatnio zmodyfikowano 2014-08-28 00:34
Autor Wiadomość
Laszlo900
Temat założony przez niniejszego użytkownika
[C++/CLI, Visual Studio 2012] Problem z wątkami z biblioteki System::Thread
» 2014-08-26 00:10:25
Witajcie, mam nadzieję, że trafiłem dobrze i żadnego nadgorliwca nie zbulwersuję.
Jestem raczej paraprogramistą. Tworzyłem na własne potrzeby aplikację win32 w Visual Studio 2012, w której korzystałem z biblioteki <thread>. Kiedy postanowiłem dodać obsługę okienkową Windows Forms, projekt zmienił się z win32 na clr, które nie wspiera bibl. <thread>. Korzystam więc z nowej biblioteki: System::Thread. W aplikacji, dane przychodzące do pewnego bufora trafiają następnie w każdej iteracji do osobnych wątków, gdzie są wyświetlane na wykresach. Po wysłaniu iteracyjnie danej do każdego wątku, operacja jest powtarzana. Liczba obiektów jest z góry znana - wprowadzona w wyświetlonym okienku Windows Forms. Problem polega na tym, że nie mogę do wektora std::vector<NazwaKlasy^>NazwaWektora dodać obiektu wątku metodą NazwaWektora[NumerPorzadkowy].push_back(NazwaObiektuWatku), ponieważ zwracany jest błąd:

"error C3699: '&&' : cannot use this indirection on type NazwaKlasy^"

Czytałem o obsłudze tych daszków ^ oraz delegatów na MSDN, jednak po wielu najróżniejszych próbach postanowiłem zwrócić się z problemem na forum. Dodam, że mamy tu do czynienia z tzw. "managed class", opisywaną przez ref class NazwaKlasy. Bez pożądanego wektora, miałem jedynie możliwość tworzenia ręcznie po kolei wątków następującymi poleceniami (wątki z obsługiwanym zewnętrznie parametrem):
1: ThreadWithState^ tws = gcnew ThreadWithState();
2: Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) );

Ktoś ma pomysł jak dodać iteracyjnie obiekty wątków (wątki) do tego lub podobnego wektora, tak, aby móc dynamicznie modyfikować atrybuty wątków?


Załączam definicję klasy:

ref class ThreadWithState
{
public:
    float* zmienna; //proszę nie krzyczeć, ona będzie prywatna, z metodą dostępową

    ThreadWithState()
    {
       
    }

   void ThreadProc()
   {
      Wykres* wykres1 = new Wykres();
      wykres1->rysuj(zmienna);

   }
};

Wątki są tworzone zgodnie z przykładem z MSDN: http://msdn.microsoft.com/en-us/library/ts553s52(v=vs.110).aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1


P-116100
DejaVu
» 2014-08-26 00:53:52
Daszek to nie delegat. Daszek to wskaźnik na pamięć zarządzaną (występuje managed C++), a gwiazdka to wskaźnik na pamięć niezarządzaną. Skoro trzymasz w vectorze wskaźniki zarządzane to musisz po prostu zaalokować taki obiekt dynamicznie.

/edit:
Upraszczając:
C/C++
std::vector < int ^> kontener;
kontener.push_back( gcnew int( 123 ) );
P-116101
Laszlo900
Temat założony przez niniejszego użytkownika
» 2014-08-26 01:23:47
Dzięki wielkie za szybką odpowiedź i sugestię. Spróbowałem pokombinować, jednak nie podołałem problemowi. Wiedząc, na jakim miejscu się skupić, daję namiar na kod:

std::vector<ThreadWithState^> ThreadsWithState;
std::vector<Thread^> Threads;

ThreadWithState^ tws = gcnew ThreadWithState();
ThreadsWithState.push_back(tws);
Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) );
Threads.push_back(t);

Niestety, zmieniwszy ThreadsWithState.push_back(tws) na ThreadsWithState.push_back(gcnew ThreadWithState(tws)), bądź na ThreadsWithState.push_back(gcnew ThreadWithState()) i inne, podobne kombinacje, wyskakuje błąd o zbyt dużej ilości argumentów funkcji

Dla:
ThreadWithState^ tws = gcnew ThreadWithState();
ThreadsWithState.push_back(gcnew ThreadWithState());
Thread^ t = gcnew Thread( gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) );
Threads.push_back(gcnew Thread(gcnew ThreadStart(tws, &ThreadWithState::ThreadProc ) ));

przynajmniej nie podkreśla składni, ale przy kompilacji jest znowu tylko błąd opisywany w temacie. Kończą mi się pomysły i chyba czekają mnie długie godziny z dokumentacją MSDN. Z góry dziękuję za następne sugestie
P-116102
DejaVu
» 2014-08-26 01:31:16
http://msdn.microsoft.com​/en-us/library/bb386284.aspx

http://www.cplusplus.com/forum​/windows/62119/
Frazy, które należy wpisać w wyszukiwarkę google:

http:/​/social.msdn.microsoft.com​/Forums/vstudio/en-US​/5c0c5700-9442-4cb2-83ce-fcc21e​c64789​/c-stl-vector-class-behavior-w​ithin-a-managed-class​?forum=vcgeneral

unfortunately the STL does not support managed code.

Innymi słowy: użyj kontenera z Managed C++, a nie z STL-a :)

/edit:
Niestety C++, a Managed C++ (C++/CLI) to w zasadzie różne języki programowania, które mają 'trochę' wspólnego mianownika. Osobiście polecam Ci C# jeżeli chcesz tworzyć aplikację okienkową. C# jest lepszy pod wieloma względami od C++, jeżeli wydajność nie jest kluczowym elementem, a i to da radę osiągnąć w łatwy sposób pisząc biblioteki dynamiczne do samych obliczeń w C++.
P-116103
Laszlo900
Temat założony przez niniejszego użytkownika
» 2014-08-28 00:34:53
Dzięki raz jeszcze. Niestety na drodze wielogodzinnych prób przy pomocy MSDN, potwierdzałby się fakt, że takiego szpagatu zrobić się nie da. Proponowane zamienniki mojego wektora:  List, set, array z tegoż samego frameworku nie mogą obsłużyć obiektów takich klas, mimo iż potencjalnie do podobnych rzeczy się nadają. W projekcie, na drodze desperacji, stworzyłem na stałe 10 wątków i bardzo brzydkiego switch case'a, który w zależności od liczby stworzonych obiektów, którym przypisywane są wątki, startuje tyle wątków, ile jest obiektów (a miało być tak pięknie). W MSDN kierują rozwiązanie do rzeczy takich, jak np. BackgroundWorker, bazującego zdaje się na eventach, ale wgryzienie się w to zostawiam na koniec projektu.
P-116312
« 1 »
  Strona 1 z 1