Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8764107
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T15:56:51+00:00 2026-06-13T15:56:51+00:00

I am using a third party library that iterates over some very large flat

  • 0

I am using a third party library that iterates over some very large flat files which can take many minutes. The library provides an Enumerator so you can yield each result and process it while the enumerator then extracts the next item in the flat file.

eg:

IEnumerable<object> GetItems()
{
    var cursor = new Cursor;

    try
    {
        cursor.Open();

        while (!cursor.EOF)
        {
            yield return new //object;

            cursor.MoveNext();
        }

    }
    finally
    {
        if (cursor.IsOpen)
        {
            cursor.Close();
        }
    }
}

What I am trying to achieve is to have two consumers of the same Enumerable so I don’t have to extract the information twice and so each consumer can still process each item as it arrives with out having to wait for all the times to arrive at once.

IEnumerable<object> items = GetItems();

new Thread(SaveToDateBase(items)).Start();
new Thread(SaveSomewhereElse(items)).Start();

I guess what I am trying to achieve is something like

“if the item the consumer is asking for is already extracted then yield it, otherwise move next and wait” but I am conscious of possible MoveNext() clashes between the two threads.

Does something like this already exits if not any thoughts on how it would be achieved?

Thanks

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T15:56:52+00:00Added an answer on June 13, 2026 at 3:56 pm

    Essentially what you want is to cache an IEnumerable<T>‘s data, but without waiting for it to finish before storing it. You can do something like this:

    public static IEnumerable<T> Cache<T>(this IEnumerable<T> source)
    {
        return new CacheEnumerator<T>(source);
    }
    
    private class CacheEnumerator<T> : IEnumerable<T>
    {
        private CacheEntry<T> cacheEntry;
        public CacheEnumerator(IEnumerable<T> sequence)
        {
            cacheEntry = new CacheEntry<T>();
            cacheEntry.Sequence = sequence.GetEnumerator();
            cacheEntry.CachedValues = new List<T>();
        }
    
        public IEnumerator<T> GetEnumerator()
        {
            if (cacheEntry.FullyPopulated)
            {
                return cacheEntry.CachedValues.GetEnumerator();
            }
            else
            {
                return iterateSequence<T>(cacheEntry).GetEnumerator();
            }
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }
    
    private static IEnumerable<T> iterateSequence<T>(CacheEntry<T> entry)
    {
        for (int i = 0; entry.ensureItemAt(i); i++)
        {
            yield return entry.CachedValues[i];
        }
    }
    
    private class CacheEntry<T>
    {
        public bool FullyPopulated { get; private set; }
        public IEnumerator<T> Sequence { get; set; }
    
        //storing it as object, but the underlying objects will be lists of various generic types.
        public List<T> CachedValues { get; set; }
    
        private static object key = new object();
        /// <summary>
        /// Ensure that the cache has an item a the provided index.  If not, take an item from the 
        /// input sequence and move to the cache.
        /// 
        /// The method is thread safe.
        /// </summary>
        /// <returns>True if the cache already had enough items or 
        /// an item was moved to the cache, 
        /// false if there were no more items in the sequence.</returns>
        public bool ensureItemAt(int index)
        {
            //if the cache already has the items we don't need to lock to know we 
            //can get it
            if (index < CachedValues.Count)
                return true;
            //if we're done there's no race conditions hwere either
            if (FullyPopulated)
                return false;
    
            lock (key)
            {
                //re-check the early-exit conditions in case they changed while we were
                //waiting on the lock.
    
                //we already have the cached item
                if (index < CachedValues.Count)
                    return true;
                //we don't have the cached item and there are no uncached items
                if (FullyPopulated)
                    return false;
    
                //we actually need to get the next item from the sequence.
                if (Sequence.MoveNext())
                {
                    CachedValues.Add(Sequence.Current);
                    return true;
                }
                else
                {
                    Sequence.Dispose();
                    FullyPopulated = true;
                    return false;
                }
            }
        }
    }
    

    Example usage:

    private static IEnumerable<int> interestingIntGenertionMethod(int maxValue)
    {
        for (int i = 0; i < maxValue; i++)
        {
            Thread.Sleep(1000);
            Console.WriteLine("actually generating value: {0}", i);
            yield return i;
        }
    }
    
    public static void Main(string[] args)
    {
        IEnumerable<int> sequence = interestingIntGenertionMethod(10)
            .Cache();
    
        int numThreads = 3;
        for (int i = 0; i < numThreads; i++)
        {
            int taskID = i;
            Task.Factory.StartNew(() =>
            {
                foreach (int value in sequence)
                {
                    Console.WriteLine("Task: {0} Value:{1}",
                        taskID, value);
                }
            });
        }
    
        Console.WriteLine("Press any key to exit...");
        Console.ReadKey(true);
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am using a third party library that provide some callbacks for a widget,
In a Java project, I am using a third-party library that loads some native
I'm using a third-party COM library from C#. There are get/set methods that take
we are using some third-party library that have some dependencies that must be referenced
I am using a third party library that mandates an iframe with some id,
My code is using a third party library that employ a singleton pattern deep
I am using a C++ third party library that places all of its classes
I'm using a COM object from a third party library that generates periodic events.
I'm using a third party library which returns a data reader. I would like
In my Cocoa application I'm using a third party C-library that is compiled in

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.