-1

I have a simple concept of a customized IEnumerator class providing an enumeration of struct/value types. (int, datetime, enum, etc)

class MyNumer : IEnumerator<int>
{
   public MyNumer(int start, int end) { _start = start; _end = end; }
   int _start;
   int _end;

   //Please just assume i've implemented the rest of IEnumerator, this is the only element that is 
   //pertinent to the question

   public bool MoveNext()
   {
      if (this.Current == 0) this.Current = _start;
      else if (this.Current <= _end) this.Current++;
      return this.Current <= _end;
   }
}

class ThreadedClass
{
   public IEnumerable<int> GetNumbers(int start, int end)  //this method can be called from multiple threads
   {
      IEnumerator<int> numer = new MyNumer(start, end);
      while (numer.MoveNext()) yield return numer.Current;
   }
}

What I'm concerned about is provided this example, if :

  1. Thread1 calls "myThreadedClass.GetNumbers(1, 10)"
  2. Thread2 calls "myThreadedClass.GetNumbers(30, 40)"
  3. Thread3 calls "myThreadedClass.GetNumbers(70, 100)"

Will I get three separate, distinct IEnumerable returned, or will the threads collide on the "yield return"?

JaedenRuiner
  • 329
  • 4
  • 18
  • 1
    Did you try to run it and see what happens? – Pavel Anikhouski Feb 02 '21 at 22:08
  • Also, the first result from google [Is yield return in C# thread-safe?](https://stackoverflow.com/questions/1379266/is-yield-return-in-c-sharp-thread-safe) – Pavel Anikhouski Feb 02 '21 at 22:10
  • 3
    Each thread has it's own stack, so yeah. There will be no collision. – Andy Feb 02 '21 at 22:20
  • The real problem is if someone passes in a value <= 0 for start and >0 for end and then you have an infinite loop – juharr Feb 02 '21 at 22:46
  • juharr - absolutely, that's all controlled in the constructor, so i wasn't concerned about that. I was just curious whether or not "yield return" would be thread safe in this circumstance, and it appears Andy (and Theodor below) answered that. Pavel - if you look at that link it isn't about this question. That is a poorly titled post, since that coder's issue is not about threading, but proper use of enumerables, since he is changing the collection after the enumerator is created. There is no collection, this is a custom enumerator. – JaedenRuiner Feb 03 '21 at 01:10

1 Answers1

0

Not only you will get three distinct IEnumerable<int> objects, but also each time you enumerate each of them a new IEnumerator<int> will be created, with its own distinct internal instance of the MyNumer class. So there would be no thread safety issue even if all three threads were sharing the same IEnumerable<int> instance, returned by a single invocation of the GetNumbers method.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104