Dies ist das erste Mal, dass ich mit einer parallelen for-Schleife arbeite und die Grundlagen verstehe, wie Sie mit meinem Code unten sehen können, aber ich verstehe nicht, wie man die Variablen einbaut der Schleifenfaden sicher.Verwenden einer threadsicheren Variablen mit einer parallelen for-Schleife C#
Ich folge den Artikel zu einem https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-write-a-parallel-for-loop-with-thread-local-variables
Ich bin derzeit konstanten Fehler für immer: Sequenz enthält keine Elemente in meinen Berechnungen Klasse, wenn es um die Berechnungen auf den Daten durchgeführt wird. Fehle ich etwas Einfaches, um das alles threadsicher zu machen?
UPDATE: Ich habe den gesamten relevanten Code für die Calculations-Klasse hinzugefügt, der eine Methode als Beispiel zeigt, die konstant zurückgibt. Sequence enthält keine Element-Exceptions und was ich bisher getan habe, um das Problem zu beheben (Ausnahmen laufen noch))
UPDATE 2: Ich habe die benutzerdefinierten Klassen in meinem Code hinzugefügt, die es jetzt kompilieren sollten.
public static async Task Test()
{
Vector<double> vectorArrayBuy = null;
Vector<double> vectorArraySell = null;
Calculations calcTemp = null;
try
{
using (financeEntities context = new financeEntities())
{
List<string> symbolList = new List<string>();
symbolList = GetStockSymbols("nasdaq");
foreach (string symbol in symbolList)
{
var query = await context.DailyStockDatas.Where(i => i.Symbol == symbol && i.Market == "nasdaq").ToListAsync();
if (query.Count >= 200)
{
List<MultipleRegressionInfo> listMRInfo = new List<MultipleRegressionInfo>();
Calculations calc = new Calculations(query, j);
calcTemp = calc;
Parallel.For(0, 200, j =>
{
var targetValueBuy = calc.ListCalculationData.Select(i => i.MRTargetValueBuy).ToList();
var targetValueSell = calc.ListCalculationData.Select(i => i.MRTargetValueSell).ToList();
vectorArrayBuy = CreateVector.Dense(targetValueBuy.ToArray());
vectorArraySell = CreateVector.Dense(targetValueSell.ToArray());
var name = calc.ListCalculationData.First();
IEnumerable<double> value;
value = calc.ListCalculationData.Select(i => i.WilliamsR);
MultipleRegressionInfo r1 = Rn(value, vectorArrayBuy, nameof(name.WilliamsR), j, calc);
listMRInfo.Add(r1);
});
class Calculations
{
public List<DailyStockData> Data { get; set; }
public ConcurrentBag<CalculationData> ListCalculationData { get; set; }
public Calculations(List<DailyStockData> dailyData, int days)
{
lock (thisLock)
{
Data = dailyData;
// initiate the data
ListCalculationData = new ConcurrentBag<CalculationData>();
for (int i = 0; i < Data.Count; i++)
{
var currentDate = Data.ElementAt(i).Date;
CalculationData calc = new CalculationData(currentCalcData);
calc.WilliamsR = CalculateWilliamsR(days, currentDate);
// add current calculator class to the list
ListCalculationData.Add(calc);
}
}
}
public double CalculateWilliamsR(int days, DateTime startingDate)
{
double williamsR = 0;
double highestHigh = 0;
double currentClose = 0;
double lowestLow = 0;
try
{
highestHigh = FindMaxOrMin(days, startingDate, MaxOrMinType.HighestHigh);
lowestLow = FindMaxOrMin(days, startingDate, MaxOrMinType.LowestLow);
currentClose = (double)Data.Where(i => i.Date <= startingDate).Last().Close;
williamsR = -100 * ((highestHigh - currentClose)/(highestHigh - lowestLow));
}
catch (Exception ex)
{
williamsR = 0;
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return williamsR;
}
public enum MaxOrMinType
{
HighestHigh,
LowestLow,
HighestClose,
LowestClose
}
public double FindMaxOrMin(int days, DateTime startingDate, MaxOrMinType type)
{
double maxMin = 0;
try
{
lock (thisLock)
{
switch (type)
{
// gets Sequence contains no elements exceptions at all of the below lines
case MaxOrMinType.HighestClose:
maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Max(i => i.Close);
break;
case MaxOrMinType.HighestHigh:
maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Max(i => i.High);
break;
case MaxOrMinType.LowestClose:
maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Min(i => i.Close);
break;
case MaxOrMinType.LowestLow:
maxMin = (double)Data.Where(i => i.Date <= startingDate).Take(days).Min(i => i.Low);
break;
default:
break;
}
}
}
catch (Exception ex)
{
maxMin = 0;
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
return maxMin;
}
public class DailyStockData
{
public DailyStockData();
public int ID { get; set; }
public string Symbol { get; set; }
public string Market { get; set; }
public DateTime Date { get; set; }
public decimal Open { get; set; }
public decimal High { get; set; }
public decimal Low { get; set; }
public decimal Close { get; set; }
public decimal AdjustedClose { get; set; }
public long Volume { get; set; }
}
public class CalculationData
{
public CalculationData(CalculationData calcData)
{
Date = calcData.Date;
Open = calcData.Open;
High = calcData.High;
Low = calcData.Low;
Close = calcData.Close;
AdjustedClose = calcData.AdjustedClose;
Volume = calcData.Volume;
WilliamsR = calcData.WilliamsR;
}
public CalculationData() { }
public DateTime Date { get; set; }
public double Open { get; set; }
public double High { get; set; }
public double Low { get; set; }
public double Close { get; set; }
public double AdjustedClose { get; set; }
public double Volume { get; set; }
public double WilliamsR { get; set; }
}
Kommentare sind nicht für längere Diskussion; Diese Konversation wurde [in den Chat verschoben] (http://chat.stackoverflow.com/rooms/157820/discussion-on-question-by-user3610374-using-a-thread-safe-variable-with-a-parall) . – Andy