// Threadlokale_Variablen.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<int>^ zahlen;
   int summe;

public:
   Datensammlung()
   {
      zahlen = gcnew List<int>(); 
      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::ToInt32(eingabe) );
      }

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

   double mittelwert()
   {
      Parallel::For<long>(0, zahlen->Count, 
                          gcnew Func<long>(this, &Datensammlung::mw_init),
                          gcnew Func<int, ParallelLoopState^, long, long>(this, &Datensammlung::mw_berechnen),
                          gcnew Action<long>(this, &Datensammlung::mw_abschliessen));

      return summe / zahlen->Count;
   }


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

      return s;
   }

private:
   long mw_init() { return 0; }

   long mw_berechnen(int n, ParallelLoopState^ status, long zwischenergebnis) 
   { 
      // simuliere eine längere Tätigkeit
      Thread::SpinWait(Int32::MaxValue);
      zwischenergebnis = zahlen[n]; 
      return zwischenergebnis; 
   }

   void mw_abschliessen(long n) 
   { 
      Interlocked::Add(summe, n); 
   }

};




int main(array<System::String ^> ^args)
{
   Console::WriteLine("\n Schleifen parallelisieren \n");

   Datensammlung^ daten = gcnew Datensammlung();
   Console::WriteLine("\n Mittelwert wird berechnet \n");

   Console::WriteLine("\n Inhalt von daten: " + daten);
   Console::WriteLine("\n Mittelwert: " + daten->mittelwert());

   Console::ReadLine();
   return 0;
}

