gpt4 book ai didi

c# - 将类添加到列表 C# 时,索引超出数组范围

转载 作者:行者123 更新时间:2023-11-30 13:19:09 25 4
gpt4 key购买 nike

异常:索引在数组的边界之外。

首先,我很熟悉这个异常并且我之前已经修复它但是我在我的代码中的一个非常奇怪的行得到这个异常。当我将用户创建的类添加到我的代码中的类列表时,它被抛出。我完全不知道它为什么抛出这个异常以及如何修复它。

public static async Task getData()
{
// initialize everything
List<StockData> stockData = new List<StockData>();
List<StockMarketCompare> stockCompareData = new List<StockMarketCompare>();
List<StockData> sandpInfo = new List<StockData>();
List<StockData> sandpDateInfo = new List<StockData>();
List<StockData> amexList = new List<StockData>();
List<DateTime> completedDates = new List<DateTime>();
SymbolInfo symbolClass = new SymbolInfo();
List<SymbolInfo> ratingSymbols = new List<SymbolInfo>();
List<StockRating> ratingList = new List<StockRating>();
bool isGoodToGo = false;
string symbol, market;
int activeSymbolsCount = 0;
int rowCount = 0, completedRowCount = 0;
DateTime date = new DateTime();
DateTime searchDate = new DateTime();

using (SqlConnection connection = new SqlConnection("connectionstring"))
using (SqlCommand sandpCommand = new SqlCommand("select * from dbo.DailyGlobalData where Symbol='" + Calculations.sp500 + "'", connection))
using (SqlDataAdapter sandpAdapter = new SqlDataAdapter(sandpCommand))
using (DataTable sandpTable = new DataTable("sandp"))
using (SqlCommand stockRatingsCommand = new SqlCommand("select * from dbo.StockRatings", connection))
using (SqlDataAdapter stockRatingsAdapter = new SqlDataAdapter(stockRatingsCommand))
using (DataTable stockRatingsTable = new DataTable("stockratings"))
{
try
{
// fill the sandptable
sandpAdapter.Fill(sandpTable);

if (sandpTable != null)
{
var sandpQuery = from c in sandpTable.AsEnumerable()
select new StockData { Close = c.Field<decimal>("Close"), Date = c.Field<DateTime>("Date"), High = c.Field<decimal>("High"), Low = c.Field<decimal>("Low"), Volume = c.Field<Int64>("Volume") };
sandpInfo = sandpQuery.AsParallel().ToList();
}

// fill the stockratingstable
stockRatingsAdapter.Fill(stockRatingsTable);

if (stockRatingsTable != null)
{
activeSymbolsCount = stockRatingsTable.Rows.Count;

var symbolsAmountQuery = from c in stockRatingsTable.AsEnumerable()
select new SymbolInfo { Symbol = c.Field<string>("Symbol"), Market = c.Field<string>("Market") };
ratingSymbols = symbolsAmountQuery.AsParallel().ToList();
}

for (int i = 0; i < activeSymbolsCount; i++)
{
symbol = ratingSymbols.AsParallel().ElementAtOrDefault(i).Symbol;
market = ratingSymbols.AsParallel().ElementAtOrDefault(i).Market;
ratingList = new List<StockRating>();

using (SqlCommand historicalRatingsCommand = new SqlCommand("select * from dbo.OldStockRatings where Symbol='" + symbol + "' and Market='" + market + "'", connection))
using (SqlDataAdapter historicalRatingsAdapter = new SqlDataAdapter(historicalRatingsCommand))
using (DataTable historicalRatingsTable = new DataTable("historicalratings"))
{
// fill the historical ratings table
historicalRatingsAdapter.Fill(historicalRatingsTable);

if (historicalRatingsTable != null)
{
completedRowCount = historicalRatingsTable.AsEnumerable().AsParallel().Count();
completedDates = historicalRatingsTable.AsEnumerable().AsParallel().Select(d => d.Field<DateTime>("Date")).ToList();
}
}
using (SqlCommand amexCommand = new SqlCommand("select * from dbo.DailyAmexData where Symbol='" + symbol + "'", connection))
using (SqlDataAdapter amexAdapter = new SqlDataAdapter(amexCommand))
using (DataTable amexTable = new DataTable("amexdata"))
{
// fill the amex data table
amexAdapter.Fill(amexTable);

if (amexTable != null)
{
var amexFillQuery = from c in amexTable.AsEnumerable()
select new StockData { Close = c.Field<decimal>("Close"), Date = c.Field<DateTime>("Date"), High = c.Field<decimal>("High"), Low = c.Field<decimal>("Low"), Volume = c.Field<Int64>("Volume") };
amexList = amexFillQuery.AsParallel().ToList();

rowCount = amexList.AsParallel().Count();
}
}

Parallel.For(0, rowCount - 30, new ParallelOptions
{
MaxDegreeOfParallelism = Environment.ProcessorCount
}, async j =>
{
if (amexList.AsParallel().Count() > 0)
{
date = amexList.AsParallel().ElementAtOrDefault(j).Date;
searchDate = date.Subtract(TimeSpan.FromDays(60));

if (completedDates.Contains(date) == false)
{
var amexQuery = from c in sandpInfo
where c.Date >= searchDate && c.Date <= date
join d in amexList on c.Date equals d.Date
select new StockMarketCompare { stockClose = d.Close, marketClose = c.Close };

var amexStockDataQuery = from c in amexList
where c.Date >= searchDate && c.Date <= date
select new StockData { Close = c.Close, High = c.High, Low = c.Low, Volume = c.Volume, Date = c.Date };

stockCompareData = amexQuery.AsParallel().ToList();
stockData = amexStockDataQuery.AsParallel().ToList();
isGoodToGo = true;
}
else
{
isGoodToGo = false;
}
}

if (completedDates.Contains(date) == false)
{
var sandpDateQuery = from c in sandpInfo
where c.Date >= searchDate && c.Date <= date
select c;
sandpDateInfo = sandpDateQuery.AsParallel().ToList();
symbolClass = new SymbolInfo() { Symbol = symbol, Market = market };
isGoodToGo = true;
}
else
{
isGoodToGo = false;
}

if (isGoodToGo)
{
StockRating rating = performCalculations(symbolClass, date, sandpInfo, stockData, stockCompareData);

if (rating != null)
{
**ratingList.Add(rating);** // getting the exception thrown here
}
}
});

// now save the results to the table outside the parallel for loop

ratingList.RemoveAll(item => item == null);
List<StockRating> masterList = ratingList.DistinctBy(j => j.date).ToList();
saveToTable(masterList, symbol, market);
// close the connection
connection.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
// close the connection
connection.Close();
}
}
}

最佳答案

List<T>不是线程安全的,你正在调用 .Add从你的内部 Parallel.For .您要么需要锁定 Add或者在 System.Collections.Concurrent 中使用线程安全集合命名空间。

这不是您遇到的唯一线程错误,例如也在您的 Parallel.For 中您分配几个变量,这些变量都在循环外的范围内声明。您的各种线程将互相覆盖并分配这些值。

关于c# - 将类添加到列表 C# 时,索引超出数组范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28312339/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com