c# - C# 中的状态机

标签 c#

我正在尝试弄清楚这段代码发生了什么。我有两个线程在范围内迭代,我试图了解当第二个线程调用 GetEnumerator() 时发生了什么。特别是这一行 (T current = start;),似乎通过第二个线程在该方法中产生了一个新的“实例”。

看到 DateRange 类只有一个实例,我试图理解为什么第二个线程不捕获第一个线程修改的“当前”变量。

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();
        }
    }

最佳答案

他们都使用相同的 IEnumerable<T> , 但不同 IEnumerator<T> 秒。每次输入 for each in使用 IEnumerable 循环, GetEnumerator 被调用,返回一个单独的 IEnumerator 和它自己的状态。

关于c# - C# 中的状态机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2879757/

相关文章:

c# - LINQ to SQL - 连接、分组和求和

C#取消一个非循环的长时间运行的任务

c# - 为 List<T>() 提供大小参数

c# - 如何获取显示隐藏系统托盘图标的窗口的隐藏窗口句柄

c# - 为什么我的静态类没有在 ASP.NET MVC 中初始化?

c# - WPF,创建自定义 DataGridTextColumn 以防止不需要的字符

c# - RichTextBlock 选定文本 UWP

c# - 对简单类型使用结构而不是类

c# - memcached 的序列化

c# - 如何替换可枚举集合的默认 CollectionView?