State machines in C#

Posted by Sir Psycho on Stack Overflow See other posts from Stack Overflow or by Sir Psycho
Published on 2010-05-21T05:28:52Z Indexed on 2010/05/21 5:30 UTC
Read the original article Hit count: 344

Filed under:

Hi,

I'm trying to work out what's going on with this code. I have two threads iterating over the range and I'm trying to understand what is happening when the second thread calls GetEnumerator(). This line in particular (T current = start;), seems to spawn a new 'instance' in this method by the second thread.

Seeing that there is only one instance of the DateRange class, I'm trying to understand why this works. Thanks in advance.

class Program {

        static void Main(string[] args) {

            var daterange = new DateRange(DateTime.Now, DateTime.Now.AddDays(10), new TimeSpan(24, 0, 0));

            var ts1 = new ThreadStart(delegate {

                foreach (var date in daterange) {
                    Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " " + date);
                }
            });

            var ts2 = new ThreadStart(delegate {

                foreach (var date in daterange) {
                    Console.WriteLine("Thread " + Thread.CurrentThread.ManagedThreadId + " " + date);
                }
            });

            Thread t1 = new Thread(ts1);

            Thread t2 = new Thread(ts2);

            t1.Start();
            Thread.Sleep(4000);
            t2.Start();

            Console.Read();
        }
    }

    public class DateRange : Range<DateTime> {

        public DateTime Start { get; private set; }
        public DateTime End { get; private set; }
        public TimeSpan SkipValue { get; private set; }


        public DateRange(DateTime start, DateTime end, TimeSpan skip) : base(start, end) {
            SkipValue = skip;
        }

        public override DateTime GetNextElement(DateTime current) {

            return current.Add(SkipValue);
        }
    }

    public abstract class Range<T> : IEnumerable<T> where T : IComparable<T> {

        readonly T start;
        readonly T end;


        public Range(T start, T end) {

            if (start.CompareTo(end) > 0)
                throw new ArgumentException("Start value greater than end value");

            this.start = start;
            this.end = end;
        }

        public abstract T GetNextElement(T currentElement);

        public IEnumerator<T> GetEnumerator() {

            T current = start;

            do {
                Thread.Sleep(1000);

                yield return current;

                current = GetNextElement(current);

            } while (current.CompareTo(end) < 1);
        }       

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() {
            return GetEnumerator();
        }
    }

© Stack Overflow or respective owner

Related posts about c#