简体   繁体   中英

C#: How to stop looping through data in a csv file and store last read value

I have a windows forms application that picks up a csv file and loops through the customer IDs in them. for each customer ID it does an update.

I have two questions:

  1. I have a pause button, which should stop processing the customerIDs in the csv file, and store the last process customerID. How can I stop going through the customerIDs in the csv and store the last processed customerID?

  2. The next time I start the application, it should start processing after the last processed customer ID

Please can you advice me on how I can do that?

//initially the customerID will be 0
int customerID = 0;
string inputFilePath = "C:\\customer_refno\\customerids.csv";
using (StreamReader input = File.OpenText(inputFilePath))
using (CsvReader csvread = new CsvReader(input))
{
    IEnumerable<dynamic> records = csvread.GetRecords<dynamic>();
    //StringBuilder buildtext = new StringBuilder();
    foreach (var record in records)
    {
        //process customerID
        lastProcessed = record.CustomerID;

    }
}

private void btpause_click(object sender, EventArgs e)
{
    //complete processing the currently processing customerID and stop
    //store last processed customer ID 
}

You can do it by storing the position of underlining Stream. But be aware of the buffer, may be some in same block of the file need to be skiped.

Here a sample:

    private static long _lastPos = 0;//Store this in a file and load on Apllication start
    private static int _lastProcessed = -1;//Store this in a file and load on Apllication start
    private static int _bufferSize = 4096;
    private static bool _break = true; //Set or reset in btpause_click


    static void Main(string[] args)
    {
        Loop();
        Loop();
        Loop();


    }

    private static void Loop()
    {
        int customerID = 0;
        string inputFilePath = "D:\\temp\\customerids.csv";
        using (StreamReader input = new StreamReader(inputFilePath, Encoding.UTF8, true, _bufferSize))
        {
            if (_lastPos > 0) input.BaseStream.Position = _lastPos;
            using (CsvReader csvread = new CsvReader(input, new Configuration(){Delimiter = "\t"}))
            {
                IEnumerable<dynamic> records = csvread.GetRecords<dynamic>();
                //StringBuilder buildtext = new StringBuilder();
                foreach (var record in records)
                {
                    //process customerID
                    var cosId = Int32.Parse(record.CustomerID);
                    if (_lastProcessed >= cosId) continue; //Skip to next if lower than processed
                    _lastProcessed = cosId;

                    _lastPos = input.BaseStream.Position - _bufferSize;
                    Console.WriteLine(" > " + record.CustomerID + "\t" + record.Name);
                    if (_break) {
                       //Do staff needed at the break, like save variables
                       break;
                    }
                }
            }
        }
    }

-- Edit 1 -- you can stop the loop by set _break to true (normally it should be false in the Sample it is tru to show how to just get one costumer) If you need to get a feedback :

private void btpause_click(object sender, EventArgs e)
{
    _break = true;
}

// ...
private static void Loop()
  //... Modify loop, also see first sample in the case break is set:
  Console.WriteLine(" > " + record.CustomerID + "\t" + record.Name);
  if (_break) {
      //Do staff needed at the break, like save variables
      break;
  }
  //....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM