我正在試着弄清楚這段代碼是怎麼回事。我有兩個線程迭代範圍,我試圖瞭解第二個線程調用GetEnumerator()時發生了什麼。特別是這條線(T current = start;)似乎在第二個線程中產生了一個新的「實例」。C中的狀態機#
看到只有一個DateRange類的實例,我試圖理解爲什麼第二個線程不捕獲由第一個線程修改的'current'變量。
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通常不是線程安全的,如果您希望多個線程在一個線程上工作,通常最好有一個線程枚舉並將工作分配給其他線程,這就是並行Linq和並行foreach的工作方式。 – Mant101 2010-05-21 10:32:06