J
Javier Waldo
Guest
Hi,
I do not understand why I get race condition on this program, for me it seems that there is no problem, I don't understand why the threads mix the data, because for me it seems like I am creating new instances for each thread.
What am I doing wrong? How can I solve this proble without using locks (I cant use locks because that would slow down the program that is more complex that the one shown here)?
Thanks in advance I attach the code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.IO;
namespace NoSubClass
{
class Program
{
//inputs
private static string path = @Q:\FV\MOD-03 (Shadings Simulation)\FASE 2 (RayTracing)\01 - Modelo\postes\nuevoformato.txt;
private static string resultsPath = @Q:\FV\MOD-03 (Shadings Simulation)\FASE 2 (RayTracing)\01 - Modelo\tracker_results\;
private static double A = 4;
private static double R = 10;
private static double maxTilt = 55.0 * Math.PI / 180;
private static int Cx = 100;
private static int Cy = 100;
private static int nThreads = 2;
private static Tracker[] allTrackers = null;
private static List<Tracker[]> TrackerGroups = null;
private static int trackingStrategy = 0; //0-->ltrue tracking; 1-->backtracking
static void Main(string[] args)
{
Program.Run();
Console.ReadLine();
}
public static async void Run()
{
//import
allTrackers = Import.ImportTrackers(path, A, R, maxTilt, Cx, Cy);
TrackerGroups = Import.splitList(nThreads, allTrackers.ToList());
Task[] tasks = new Task[TrackerGroups.Count()];
//loop over group of trackers
for (int g = 0; g < TrackerGroups.Count(); g++)
{
// progressBar1.Maximum = TrackerGroups[0].Count();
int p = 0;
int G = g;
Tracker[] groupTrackers = TrackerGroups[G];
Tracker[] tempallTrackers = allTrackers;
double a = A;
double r = R;
double cx = Cx;
double cy = Cy;
double maxtilt = maxTilt;
int tracking = trackingStrategy;
tasks[G] = new Task(() =>
{
//loop over trackers on group
for (int t = 0; t < TrackerGroups[G].Count(); t++)
{
int temp = t;
//set parameters of tracker to study
Tracker tracker = TrackerGroups[G][temp];
Plant plt = new Plant();
plt.calculateShadows(allTrackers, tracker, temp, G);
}
});
tasks[G].Start();
//progressBar1.Value = g;
p++;
}
await Task.WhenAll(tasks);
}
}
class Plant
{
private object _lck = new object();
public void calculateShadows(Tracker[] allTrackers, Tracker tracker, int track, int group)
{
tracker.SetCornerCoordinates(0.56);
tracker.SetTilt(0.56, 0.0345, 0);
double shadow = 0;
//random calculations
for (int t = 0; t < allTrackers.Count(); t++)
{
Tracker ftracker = allTrackers[t];
ftracker.SetCornerCoordinates(0.56);
shadow += 0.003 * tracker.getCornerCoordinates()[0, 0] * tracker.getCornerCoordinates()[1, 0] / (ftracker.getCornerCoordinates()[2, 1] * ftracker.getCornerCoordinates()[0, 2]);
}
Console.WriteLine("thread number " + Task.CurrentId + " shadow is: " + shadow + " tracker: " + track + " group: " + group);
}
}
class Tracker
{
//initial data (all private and imported)
private double[] northPost; //x,y,z coordinates of south post of the tracker
private double[] southPost; //x,y,z coordinates of south post of the tracker
private double A; //tracker width
private double R; //tracker pitch
private double maxTilt; //tilt limit
private int Cx, Cy; //cells divisions
//geometrical useful data
private double[,] cornerCoordinates = new double[4, 3];
private double[,,] trackerCells;
private double tilt;
private double[] normal;
//------------Methods-----------------
//Set initial data:
public void SetInitialData(double[] northPost, double[] southPost, double A, double R, double maxTilt, int Cx, int Cy)
{
this.northPost = northPost;
this.southPost = southPost;
this.A = A;
this.R = R;
this.maxTilt = maxTilt;
this.Cx = Cx;
this.Cy = Cy;
this.trackerCells = new double[Cx, Cy, 3];
//coordenadas de celdas
//0, 1, 2 - x, y, z
}
//Set tilt
public void SetTilt(double az, double ele, int tracking)
{
//tracking parameters
double sun3d_z;
double sun3d_x;
double angle3;
double eleSun2d;
double eleSun2d_treshold = Math.Asin(A / R);
sun3d_x = -Math.Cos(ele) * Math.Sin(az);
sun3d_z = Math.Sin(ele);
eleSun2d = Math.Atan2(sun3d_z, Math.Abs(sun3d_x));
if (tracking == 1 && eleSun2d < eleSun2d_treshold)
{//backtracking
angle3 = Math.PI - Math.Asin((R / A) * Math.Sin(eleSun2d));
tilt = Math.Abs(Math.PI - eleSun2d - angle3);
}
else
{//truetracking
if (ele > 0)
{
tilt = Math.Abs(Math.Atan(Math.Cos(az - Math.PI * 0.5) / Math.Tan(ele)));
}
else
{
tilt = maxTilt;
}
if (tilt > maxTilt)
{
tilt = maxTilt;
}
}
}
//Set corner coordinates
public void SetCornerCoordinates(double az)
{
//post coordinates
double xN = northPost[0];
double yN = northPost[1];
double zN = northPost[2];
double xS = southPost[0];
double yS = southPost[1];
double zS = southPost[2];
//highest north corner[0,]
cornerCoordinates[0, 0] = xN;//x
if (az > 0)
{//sun on the east
cornerCoordinates[0, 1] = yN - A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[0, 1] = yN + A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[0, 2] = zN + A * 0.5 * Math.Sin(tilt); //z
//highest south corner[1,]
cornerCoordinates[1, 0] = xS;//x
if (az > 0)
{//sun on the east
cornerCoordinates[1, 1] = yS - A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[1, 1] = yS + A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[1, 2] = zS + A * 0.5 * Math.Sin(tilt); //z
//lowest north corner[2,]
cornerCoordinates[2, 0] = xN;//x
if (az > 0)
{//sun on the east
cornerCoordinates[2, 1] = yN + A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[2, 1] = yN - A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[2, 2] = zN - A * 0.5 * Math.Sin(tilt);
//lowest south corner[3,]
cornerCoordinates[3, 0] = xS;//x
if (az > 0)
{//sun on the east
cornerCoordinates[3, 1] = yS + A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[3, 1] = yS - A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[3, 2] = zS - A * 0.5 * Math.Sin(tilt); //z
}
//getCorner coordinates
public double[,] getCornerCoordinates()
{
return cornerCoordinates;
}
}
class Import
{
public static Tracker[] ImportTrackers(string path, double A, double R, double maxTilt, int Cx, int Cy)
{
//import data of trackers
List<Tracker> listofTrackers = new List<Tracker>();
List<string> data = ConvertCSVtoDataTable(path);
bool nextTracker = true;
Tracker tracker = null;
double[] nPost = null;
double[] sPost = null;
for (int i = 0; i < data.Count; i++)
{
//save south and north post, x=y, y=x
data = data.Replace(",", ".");//replace commas for point
if (nextTracker)
{
nPost = new double[3];
sPost = new double[3];
tracker = new Tracker();
}
if (data.Split(';')[0] == "VN")
{
nPost[0] = Convert.ToDouble(data.Split(';')[2]);
nPost[1] = Convert.ToDouble(data.Split(';')[1]);
nPost[2] = Convert.ToDouble(data.Split(';')[5]);
nextTracker = false;
}
if (data.Split(';')[0] == "VS")
{
sPost[0] = Convert.ToDouble(data.Split(';')[2]);
sPost[1] = Convert.ToDouble(data.Split(';')[1]);
sPost[2] = Convert.ToDouble(data.Split(';')[5]);
tracker.SetInitialData(nPost, sPost, A, R, maxTilt, Cx, Cy);
listofTrackers.Add(tracker);
nextTracker = true;
}
}
return listofTrackers.ToArray();
}
//import .csv function
public static List<string> ConvertCSVtoDataTable(string strFilePath)
{
using (var reader = new StreamReader(strFilePath))
{
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line;
listA.Add(values);
}
return listA;
}
}
public static List<Tracker[]> splitList(int nsplits, List<Tracker> ArrayTotal)
{
List<Tracker[]> splittedLists = new List<Tracker[]>();
int step = ArrayTotal.Count() / nsplits;
for (int i = 0; i < ArrayTotal.Count(); i += step)
{
if (i + step > ArrayTotal.Count())
{
Tracker[] subArray = (ArrayTotal.GetRange(i, ArrayTotal.Count() - i)).ToArray();
splittedLists.Add(subArray);
}
else
{
Tracker[] subArray = (ArrayTotal.GetRange(i, step)).ToArray();
splittedLists.Add(subArray);
}
}
return splittedLists;
}
}
}
Continue reading...
I do not understand why I get race condition on this program, for me it seems that there is no problem, I don't understand why the threads mix the data, because for me it seems like I am creating new instances for each thread.
What am I doing wrong? How can I solve this proble without using locks (I cant use locks because that would slow down the program that is more complex that the one shown here)?
Thanks in advance I attach the code below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.IO;
namespace NoSubClass
{
class Program
{
//inputs
private static string path = @Q:\FV\MOD-03 (Shadings Simulation)\FASE 2 (RayTracing)\01 - Modelo\postes\nuevoformato.txt;
private static string resultsPath = @Q:\FV\MOD-03 (Shadings Simulation)\FASE 2 (RayTracing)\01 - Modelo\tracker_results\;
private static double A = 4;
private static double R = 10;
private static double maxTilt = 55.0 * Math.PI / 180;
private static int Cx = 100;
private static int Cy = 100;
private static int nThreads = 2;
private static Tracker[] allTrackers = null;
private static List<Tracker[]> TrackerGroups = null;
private static int trackingStrategy = 0; //0-->ltrue tracking; 1-->backtracking
static void Main(string[] args)
{
Program.Run();
Console.ReadLine();
}
public static async void Run()
{
//import
allTrackers = Import.ImportTrackers(path, A, R, maxTilt, Cx, Cy);
TrackerGroups = Import.splitList(nThreads, allTrackers.ToList());
Task[] tasks = new Task[TrackerGroups.Count()];
//loop over group of trackers
for (int g = 0; g < TrackerGroups.Count(); g++)
{
// progressBar1.Maximum = TrackerGroups[0].Count();
int p = 0;
int G = g;
Tracker[] groupTrackers = TrackerGroups[G];
Tracker[] tempallTrackers = allTrackers;
double a = A;
double r = R;
double cx = Cx;
double cy = Cy;
double maxtilt = maxTilt;
int tracking = trackingStrategy;
tasks[G] = new Task(() =>
{
//loop over trackers on group
for (int t = 0; t < TrackerGroups[G].Count(); t++)
{
int temp = t;
//set parameters of tracker to study
Tracker tracker = TrackerGroups[G][temp];
Plant plt = new Plant();
plt.calculateShadows(allTrackers, tracker, temp, G);
}
});
tasks[G].Start();
//progressBar1.Value = g;
p++;
}
await Task.WhenAll(tasks);
}
}
class Plant
{
private object _lck = new object();
public void calculateShadows(Tracker[] allTrackers, Tracker tracker, int track, int group)
{
tracker.SetCornerCoordinates(0.56);
tracker.SetTilt(0.56, 0.0345, 0);
double shadow = 0;
//random calculations
for (int t = 0; t < allTrackers.Count(); t++)
{
Tracker ftracker = allTrackers[t];
ftracker.SetCornerCoordinates(0.56);
shadow += 0.003 * tracker.getCornerCoordinates()[0, 0] * tracker.getCornerCoordinates()[1, 0] / (ftracker.getCornerCoordinates()[2, 1] * ftracker.getCornerCoordinates()[0, 2]);
}
Console.WriteLine("thread number " + Task.CurrentId + " shadow is: " + shadow + " tracker: " + track + " group: " + group);
}
}
class Tracker
{
//initial data (all private and imported)
private double[] northPost; //x,y,z coordinates of south post of the tracker
private double[] southPost; //x,y,z coordinates of south post of the tracker
private double A; //tracker width
private double R; //tracker pitch
private double maxTilt; //tilt limit
private int Cx, Cy; //cells divisions
//geometrical useful data
private double[,] cornerCoordinates = new double[4, 3];
private double[,,] trackerCells;
private double tilt;
private double[] normal;
//------------Methods-----------------
//Set initial data:
public void SetInitialData(double[] northPost, double[] southPost, double A, double R, double maxTilt, int Cx, int Cy)
{
this.northPost = northPost;
this.southPost = southPost;
this.A = A;
this.R = R;
this.maxTilt = maxTilt;
this.Cx = Cx;
this.Cy = Cy;
this.trackerCells = new double[Cx, Cy, 3];
//coordenadas de celdas
//0, 1, 2 - x, y, z
}
//Set tilt
public void SetTilt(double az, double ele, int tracking)
{
//tracking parameters
double sun3d_z;
double sun3d_x;
double angle3;
double eleSun2d;
double eleSun2d_treshold = Math.Asin(A / R);
sun3d_x = -Math.Cos(ele) * Math.Sin(az);
sun3d_z = Math.Sin(ele);
eleSun2d = Math.Atan2(sun3d_z, Math.Abs(sun3d_x));
if (tracking == 1 && eleSun2d < eleSun2d_treshold)
{//backtracking
angle3 = Math.PI - Math.Asin((R / A) * Math.Sin(eleSun2d));
tilt = Math.Abs(Math.PI - eleSun2d - angle3);
}
else
{//truetracking
if (ele > 0)
{
tilt = Math.Abs(Math.Atan(Math.Cos(az - Math.PI * 0.5) / Math.Tan(ele)));
}
else
{
tilt = maxTilt;
}
if (tilt > maxTilt)
{
tilt = maxTilt;
}
}
}
//Set corner coordinates
public void SetCornerCoordinates(double az)
{
//post coordinates
double xN = northPost[0];
double yN = northPost[1];
double zN = northPost[2];
double xS = southPost[0];
double yS = southPost[1];
double zS = southPost[2];
//highest north corner[0,]
cornerCoordinates[0, 0] = xN;//x
if (az > 0)
{//sun on the east
cornerCoordinates[0, 1] = yN - A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[0, 1] = yN + A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[0, 2] = zN + A * 0.5 * Math.Sin(tilt); //z
//highest south corner[1,]
cornerCoordinates[1, 0] = xS;//x
if (az > 0)
{//sun on the east
cornerCoordinates[1, 1] = yS - A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[1, 1] = yS + A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[1, 2] = zS + A * 0.5 * Math.Sin(tilt); //z
//lowest north corner[2,]
cornerCoordinates[2, 0] = xN;//x
if (az > 0)
{//sun on the east
cornerCoordinates[2, 1] = yN + A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[2, 1] = yN - A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[2, 2] = zN - A * 0.5 * Math.Sin(tilt);
//lowest south corner[3,]
cornerCoordinates[3, 0] = xS;//x
if (az > 0)
{//sun on the east
cornerCoordinates[3, 1] = yS + A * 0.5 * Math.Cos(tilt);//y
}
else
{//sun on the west
cornerCoordinates[3, 1] = yS - A * 0.5 * Math.Cos(tilt);//y
}
cornerCoordinates[3, 2] = zS - A * 0.5 * Math.Sin(tilt); //z
}
//getCorner coordinates
public double[,] getCornerCoordinates()
{
return cornerCoordinates;
}
}
class Import
{
public static Tracker[] ImportTrackers(string path, double A, double R, double maxTilt, int Cx, int Cy)
{
//import data of trackers
List<Tracker> listofTrackers = new List<Tracker>();
List<string> data = ConvertCSVtoDataTable(path);
bool nextTracker = true;
Tracker tracker = null;
double[] nPost = null;
double[] sPost = null;
for (int i = 0; i < data.Count; i++)
{
//save south and north post, x=y, y=x
data = data.Replace(",", ".");//replace commas for point
if (nextTracker)
{
nPost = new double[3];
sPost = new double[3];
tracker = new Tracker();
}
if (data.Split(';')[0] == "VN")
{
nPost[0] = Convert.ToDouble(data.Split(';')[2]);
nPost[1] = Convert.ToDouble(data.Split(';')[1]);
nPost[2] = Convert.ToDouble(data.Split(';')[5]);
nextTracker = false;
}
if (data.Split(';')[0] == "VS")
{
sPost[0] = Convert.ToDouble(data.Split(';')[2]);
sPost[1] = Convert.ToDouble(data.Split(';')[1]);
sPost[2] = Convert.ToDouble(data.Split(';')[5]);
tracker.SetInitialData(nPost, sPost, A, R, maxTilt, Cx, Cy);
listofTrackers.Add(tracker);
nextTracker = true;
}
}
return listofTrackers.ToArray();
}
//import .csv function
public static List<string> ConvertCSVtoDataTable(string strFilePath)
{
using (var reader = new StreamReader(strFilePath))
{
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line;
listA.Add(values);
}
return listA;
}
}
public static List<Tracker[]> splitList(int nsplits, List<Tracker> ArrayTotal)
{
List<Tracker[]> splittedLists = new List<Tracker[]>();
int step = ArrayTotal.Count() / nsplits;
for (int i = 0; i < ArrayTotal.Count(); i += step)
{
if (i + step > ArrayTotal.Count())
{
Tracker[] subArray = (ArrayTotal.GetRange(i, ArrayTotal.Count() - i)).ToArray();
splittedLists.Add(subArray);
}
else
{
Tracker[] subArray = (ArrayTotal.GetRange(i, step)).ToArray();
splittedLists.Add(subArray);
}
}
return splittedLists;
}
}
}
Continue reading...