// Parallel_For.cpp: Hauptprojektdatei.

#include "stdafx.h"

using namespace System;
using namespace System::Threading;
using namespace System::Threading::Tasks;
using namespace System::Collections::Generic;


ref class Datensammlung
{
   List<double>^ zahlen;
   int summe;

public:
   Datensammlung()
   {
      zahlen = gcnew List<double>(); 
      summe = 0;

      // Werte einlesen
      String^ eingabe = "";
      Console::WriteLine(" Werte eingeben (b zum Beenden): \n");

      while (true)
      {
         Console::Write(" Wert: ");
         eingabe = Console::ReadLine();
   
         if (eingabe == "b")
             break;      // Schleife verlassen

         zahlen->Add( Convert::ToDouble(eingabe) );
      }

      Console::WriteLine("\n");
   }

   int getLaenge() { return zahlen->Count; }

   // Methode, die ein einzelnes Element verändert
   void verdoppeln(int n)
   {
      // simuliere eine längere Tätigkeit
      Thread::SpinWait(Int32::MaxValue);
      zahlen[n] *= 2;
      Console::WriteLine(" " + n + ". Element wurde bearbeitet");
   }

   void verdoppeln()
   {
      Parallel::For(0, zahlen->Count, gcnew Action<int>(this, &Datensammlung::verdoppeln));
   }

   virtual String^ ToString() override
   {
      String^ s = " ";
      for each (int elem in zahlen)
         s += elem + " ";

      return s;
   }
};




int main(array<System::String ^> ^args)
{
   Datensammlung^ daten = gcnew Datensammlung();

   // Verdoppeln aller Elemente
   daten->verdoppeln();
   Console::WriteLine(" Datensammlung: " + daten + "\n");

   // Verdoppeln eines bestimmten Bereichs von Elementen (hier wieder die gesamte Auflistung)
   int startIndex = 0;
   int endIndex   = daten->getLaenge();
   Parallel::For(startIndex, endIndex, 
                 gcnew Action<int>(daten, &Datensammlung::verdoppeln));
   Console::WriteLine(" Datensammlung: " + daten + "\n");

   
   Console::ReadLine();
   return 0;
}
