我的PLINQ代码线程是否安全?

时间:2014-12-04 08:45:26

标签: c# parallel-processing task-parallel-library plinq parallel.foreach

我有以下代码:

static void Main(string[] args)
{
    DateTime currentDay = DateTime.Now;
    List<Task> taskList = new List<Task>();

        List<string> markets = new List<string>() { "amex", "nasdaq", "nyse", "global" };

        Parallel.ForEach(markets, market =>
        {
            Downloads.startInitialMarketSymbolsDownload(market);
        }
        );

        Console.WriteLine("All downloads finished!");
    }

public static void startInitialMarketSymbolsDownload(string market)
{
    try
    {
        object valueTypeLock = new object();
        List<string> symbolList = new List<string>() { "GOOG", "YHOO", "AAP" }

        var historicalGroups = symbolList.AsParallel().Select((x, i) => new { x, i })
                    .GroupBy(x => x.i / 100)
                    .Select(g => g.Select(x => x.x).ToArray());

        historicalGroups.AsParallel().ForAll(g => {
            lock (valueTypeLock) {
                getHistoricalStockData(g, market);
            }

        });
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        Console.WriteLine(ex.StackTrace);
    }
}

public static void getHistoricalStockData(string[] symbols, string market)
{
    // download data for list of symbols and then upload to db tables
    Uri uri;
    string url, line;
    decimal open = 0, high = 0, low = 0, close = 0, adjClose = 0;
    DateTime date;
    Int64 volume = 0;
    string[] lineArray;
    List<string> symbolError = new List<string>();
    Dictionary<string, string> badNameError = new Dictionary<string, string>();
    System.Net.ServicePointManager.DefaultConnectionLimit = 1000;

    Parallel.ForEach(symbols, 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);

                    using (ooplesfinanceEntities entity = new ooplesfinanceEntities())
                    using (WebClient client = new WebClient())
                    using (Stream stream = client.OpenRead(uri))
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        entity.Database.Connection.Open();

                        while (reader.EndOfStream == false)
                        {
                            line = reader.ReadLine();
                            lineArray = line.Split(',');

                            // if it isn't the very first line
                            if (lineArray[0] != "Date")
                            {

                                switch (market)
                                {
                                    case "amex":
                                        DailyAmexData amexData = new DailyAmexData();
                                        var amexQuery = from r in entity.DailyAmexDatas.AsParallel().AsEnumerable()
                                                        where r.Date == date
                                                        select new StockData { Close = r.AdjustedClose };

                                        List<StockData> amexResult = amexQuery.AsParallel().ToList();

                                        if (amexResult.AsParallel().Count() > 0) // **never hits this breakpoint line**
                                        {
                                            // add the row to the table if it isn't there
                                            // now checks for stock splits and updates if necessary
                                            if (amexResult.AsParallel().FirstOrDefault().Close != adjClose)
                                            {
                                                // this means there is a stock split so it needs to have the other adjusted close prices updated
                                                amexResult.AsParallel().FirstOrDefault().Close = adjClose;
                                            }
                                            else
                                            {
                                                continue;
                                            }
                                        }
                                        else
                                        {
                                            // set the data then add it
                                            amexData.Symbol = symbol;
                                            entity.DailyAmexDatas.Add(amexData);
                                        }
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }

                        // now save everything
                        entity.SaveChanges();
                        Console.WriteLine(symbol + " added to the " + market + " database!");
                    }
            }
    );
}

一切都很顺利,我没有例外,但我没有得到任何结果,代码卡在我标记的线上,内存不断射击。我认为问题出在上面的代码中,因为我可能做错了。我只是不知道从哪里开始,因为这是我第一次处理plinq /并行处理而且教程没有显示任何复杂的内容。

0 个答案:

没有答案