/// <summary> /// Asynchronously read a single line from intake /// </summary> /// <returns>A tuple consisting of the line sequence number (1-based), source number (1-based) and the line read from intake; or null as EOD mark</returns> internal async Task <Tuple <int, int, ExternalLine> > GetLineFromIntakeAsync() { // TBD: Intake is from either text file(s) or IntakeSupplier function // linePlus is a Tuple<ExternalLine,int>: Item1 = line, Item2 = source number // End-of-data indicators: * non-null linePlus.Item1 means data // * null linePlus.Item1 means end-of-data for a single source (only if asynchronous) // * null linePlus means end-of-data for all sources Tuple <ExternalLine, int> linePlus; do { linePlus = _intakeFromReader ? await _intakeReader.GetNextLineAsync() : await _config.AsyncIntakeSupplier(null); }while (linePlus != null && linePlus.Item1 == null); // ignore tuples with null lines (which in case of async _intakeFromFile denote end of each file) if (linePlus == null) { return(null); // EOD mark } var lineCnt = Interlocked.Increment(ref _lineCnt); // adjustment for header row(s) may be needed return(Tuple.Create(lineCnt, linePlus.Item2, linePlus.Item1)); }