title: Best way to read csv file in C# to improve time efficiency
body: <p>I have the following code to read in a large file, say with over a million rows. I am using Parallel and Linq approaches. Is there a better way to do it? If yes, then how?</p>
  
  <pre><code>        private static void ReadFile()
          {
              float floatTester = 0;
              List&lt;float[]&gt; result = File.ReadLines(@"largedata.csv")
                  .Where(l =&gt; !string.IsNullOrWhiteSpace(l))
                  .Select(l =&gt; new { Line = l, Fields = l.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries) })
                  .Select(x =&gt; x.Fields
                                .Where(f =&gt; Single.TryParse(f, out floatTester))
                                .Select(f =&gt; floatTester).ToArray())
                  .ToList();
  
              // now get your totals
              int numberOfLinesWithData = result.Count;
              int numberOfAllFloats = result.Sum(fa =&gt; fa.Length);
              MessageBox.Show(numberOfAllFloats.ToString());
          }
  
          private static readonly char[] Separators = { ',', ' ' };
  
          private static void ProcessFile()
          {
              var lines = File.ReadAllLines("largedata.csv");
              var numbers = ProcessRawNumbers(lines);
  
              var rowTotal = new List&lt;double&gt;();
              var totalElements = 0;
  
              foreach (var values in numbers)
              {
                  var sumOfRow = values.Sum();
                  rowTotal.Add(sumOfRow);
                  totalElements += values.Count;
              }
              MessageBox.Show(totalElements.ToString());
          }
  
          private static List&lt;List&lt;double&gt;&gt; ProcessRawNumbers(IEnumerable&lt;string&gt; lines)
          {
              var numbers = new List&lt;List&lt;double&gt;&gt;();
              /*System.Threading.Tasks.*/
              Parallel.ForEach(lines, line =&gt;
              {
                  lock (numbers)
                  {
                      numbers.Add(ProcessLine(line));
                  }
              });
              return numbers;
          }
  
          private static List&lt;double&gt; ProcessLine(string line)
          {
              var list = new List&lt;double&gt;();
              foreach (var s in line.Split(Separators, StringSplitOptions.RemoveEmptyEntries))
              {
                  double i;
                  if (Double.TryParse(s, out i))
                  {
                      list.Add(i);
                  }
              }
              return list;
          }
  
          private void button1_Click(object sender, EventArgs e)
          {
              Stopwatch stopWatchParallel = new Stopwatch();
              stopWatchParallel.Start();
              ProcessFile();
              stopWatchParallel.Stop();
              // Get the elapsed time as a TimeSpan value.
              TimeSpan ts = stopWatchParallel.Elapsed;
  
              // Format and display the TimeSpan value.
              string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                  ts.Hours, ts.Minutes, ts.Seconds,
                  ts.Milliseconds / 10);
              MessageBox.Show(elapsedTime);
  
              Stopwatch stopWatchLinQ = new Stopwatch();
              stopWatchLinQ.Start();
              ReadFile();
              stopWatchLinQ.Stop();
              // Get the elapsed time as a TimeSpan value.
              TimeSpan ts2 = stopWatchLinQ.Elapsed;
  
              // Format and display the TimeSpan value.
              string elapsedTimeLinQ = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                  ts2.Hours, ts.Minutes, ts.Seconds,
                  ts2.Milliseconds / 10);
              MessageBox.Show(elapsedTimeLinQ);
          }
  </code></pre>