我的代码完美无缺,我根本没有任何例外。它将以非常快的速度运行大约100秒,然后它会慢慢爬行。我在一个相关的问题上听了别人的建议,当它减速时,我在Vs中暂停了我的程序大约10次,并且它一直按照我将在下面标记的同一行。
我唯一的理论是我正在使用parallel foreach
循环,我相信它就像一个多线程应用程序,它在代码完成之前继续执行代码并且它正在触及循环之后的代码。它一直在减速的地方。
只是让你理解我下面的代码,表和适配器都是我在代码中访问的强类型sql数据集的一部分。我不明白速度问题如何与并行foreach循环相关...
public static void startDownload()
{
List<string> markets = new List<string>() { "amex", "global", "nasdaq", "nyse" };
Parallel.ForEach(markets, market =>
{
IEnumerable<string> symbolList = Helper.getStockSymbols(market);
var historicalGroups = symbolList.Select((x, i) => new { x, i })
.GroupBy(x => x.i / 100)
.Select(g => g.Select(x => x.x).ToArray());
historicalGroups.AsParallel().ForAll(g => Downloads.getHistoricalStockData(g, market));
});
}
// wait 24 hours before you do this again
Task.Delay(TimeSpan.FromHours(24)).Wait();
}
public static List<string> getStockSymbols(string market)
{
List<string> symbolList = new List<string>();
using (SymbolsDataTable symbolTable = new SymbolsDataTable())
using (SymbolsTableAdapter symbolAdapter = new SymbolsTableAdapter())
{
symbolAdapter.FillByActiveSymbols(symbolTable, market);
var query = from c in symbolTable
select c.Symbol;
return query.AsParallel().ToList();
}
}
public static void getHistoricalStockData(string[] symbols, string market)
{
// download data for list of symbols and then upload to db tables
Uri uri;
string url;
List<StockData> results = new List<StockData>();
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.ServicePointManager.DefaultConnectionLimit = 1000;
DailyAmexDataDataTable tempTable = new DailyAmexDataDataTable();
Parallel.ForEach(symbols, async symbol =>
{
url = "http://ichart.finance.yahoo.com/table.csv?s=" + symbol + "&a=00&b=1&c=1900&d=" + (DateTime.Now.Month - 1) + "&e=" + DateTime.Now.Day + "&f=" + DateTime.Now.Year + "&g=d&ignore=.csv";
uri = new Uri(url);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(uri);
webRequest.KeepAlive = true;
webRequest.ProtocolVersion = HttpVersion.Version10;
webRequest.ServicePoint.ConnectionLimit = 24;
webRequest.Timeout = 10000;
webRequest.Headers.Add("UserAgent", "Pentia; MSI");
Stopwatch watch = new Stopwatch();
watch.Start();
WebResponse webResponse = await webRequest.GetResponseAsync();
watch.Stop();
Debug.WriteLine(watch.ElapsedMilliseconds);
using (DailyAmexDataDataTable table = new DailyAmexDataDataTable())
using (DailyAmexDataTableAdapter adapter = new DailyAmexDataTableAdapter())
using (Stream stream = webResponse.GetResponseStream())
using (StreamReader reader = new StreamReader(stream))
{
adapter.Adapter.UpdateBatchSize = 1000;
adapter.ClearBeforeFill = true;
try
{
adapter.FillBySymbol(table, symbol);
}
bool breakLoop = false;
while (breakLoop == false && reader.EndOfStream == false)
{
Object lockDate = new Object();
lock (lockDate)
{
string[] lineArray;
string line;
line = reader.ReadLine();
lineArray = line.Split(',');
DateTime testDate = new DateTime();
bool isDate = DateTime.TryParse(lineArray[0], out testDate);
decimal open = 0, high = 0, low = 0, close = 0, adjClose = 0;
DateTime date = new DateTime();
Int64 volume = 0;
// if it isn't the very first line
if (isDate)
{
// set the data for each array here
DateTime.TryParse(lineArray[0], out date);
Decimal.TryParse(lineArray[1], out open);
Decimal.TryParse(lineArray[2], out high);
Decimal.TryParse(lineArray[3], out low);
Decimal.TryParse(lineArray[4], out close);
Int64.TryParse(lineArray[5], out volume);
Decimal.TryParse(lineArray[6], out adjClose);
var amexQuery = from c in table
where c.Date == date
select new StockData { Close = c.AdjustedClose };
results = amexQuery.AsParallel().ToList();
if (results != null)
{
breakLoop = true;
}
else
{
adapter.Insert(symbol, open, high, low, close, volume, adjClose, date);
}
}
}
}
tempTable = (DailyAmexDataDataTable)table.GetChanges();
if (tempTable != null)
{
adapter.Update(tempTable);
tempTable.Dispose();
}
}
);
}
答案 0 :(得分:2)
在我之后重复&#34;永远不会永远打电话给Task.Wait()
&#34;。
好的,我已经解决了这个问题。
每次调用Task.Wait()
都会导致线程进入休眠状态。在这种情况下,您将使所有线程池线程分别休眠24小时。这完全是疯了。结果是TPL没有任何线程可以运行代码。
执行此操作的正确方法是使用调度程序,或使用await Task.Delay(TimeSpan.FromHours(24))
代替。