Search code examples
c#csvexceptioncrashfilehelpers

Use FileHelperAsyncEngine crashed with no exception


I'm using the FileHelpers Engine FileHelperAsyncEngine<T>. Reading a large CSV file with more than 500,000 rows and I need to extract some fields to fill in an SHP file(ArcGIS).

But when I use BeginReadFile and try to select some data, the application crashes without any exception, even if I have done to get global exception. But nothing unusual has been achieved and I print the line of CSV where the thread is reading.

When the program crashes, the last line in the log file is different each time.

Here is my code:

1.Method that use FileHelpersEngine

public Dictionary<int, double> FetchByStepIndex(int stepindex)
{
    try
    {
        using (var engine = new FileHelperAsyncEngine<Mike2DDynamicData>())
        {
            using (engine.BeginReadFile(CsvPath))
            {
                var temp=new Dictionary<int, double>();
                foreach (var itemData in engine)
                {
                    if (itemData.StepIndex != stepindex) continue;
                    temp.Add(itemData.ElementID,double.Parse(itemData.TotalWaterDepth));
                    LogHelper.WriteLog(
                        itemData.StepIndex + "_" + itemData.ElementID + "_" + itemData.TotalWaterDepth,
                        LogMessageType.Info);
                }
                /* The codes when not debugging like ↓
                var temp = engine.Where(w => w.StepIndex == stepindex)
                    .Select(s => new { s.ElementID, s.TotalWaterDepth })
                    .ToDictionary(d => d.ElementID, d => d.TotalWaterDepth);
                    */
                engine.Close();
                return temp;
            }
        }
    }
    catch (FileHelpersException e)
    {
        throw e;
    }
}

2.Class:Mike2DDynamicData:

[DelimitedRecord(",")]
[IgnoreFirst]
public class Mike2DDynamicData
{
    public int StepIndex;

    [FieldNullValue(typeof(DateTime),"2017-1-1 00:00:00")]
    [FieldConverter(ConverterKind.Date,"yyyy-MM-dd HH:mm:ss")]
    public DateTime Time;
    public int ElementID;

    [FieldValueDiscarded]
    public string SurfaceElevation;

    public string TotalWaterDepth;

    [FieldValueDiscarded] public string CurrentSpeed;
}

Solution

  • For your simple csv file it is not worth the trouble to use a 3rd part dll. Just write the code yourself.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            const string FILENAME = @"c:\temp\test.csv";
            static void Main(string[] args)
            {
                new Mike2DDynamicData(FILENAME);
            }
        }
        public class Mike2DDynamicData
        {
            public static List<Mike2DDynamicData> data = new List<Mike2DDynamicData>();
    
    
            public int StepIndex;
    
            public DateTime Time;
            public int ElementID;
    
            public string SurfaceElevation;
    
            public string TotalWaterDepth;
    
            public string CurrentSpeed;
    
            public Mike2DDynamicData() { }
            public Mike2DDynamicData(string filename)
            {
    
                StreamReader reader = new StreamReader(filename);
    
                string inputline = "";
                int lineNumber = 0;
                while((inputline = reader.ReadLine()) != null)
                {
                    if (++lineNumber > 1)
                    {
                        string[] splitArray = inputline.Split(new char[] { ',' });
    
                        Mike2DDynamicData newRow = new Mike2DDynamicData();
                        data.Add(newRow);
    
                        newRow.StepIndex = int.Parse(splitArray[0]);
                        newRow.Time = DateTime.Parse(splitArray[1]);
                        newRow.ElementID = int.Parse(splitArray[2]);
                        newRow.SurfaceElevation = splitArray[3];
                        newRow.TotalWaterDepth = splitArray[4];
                        newRow.CurrentSpeed = splitArray[5];
    
                    }
                }
            }
    
    
    
        }
    
    }