BadCats
@BadCats

Yield и потоки?

class UserCollection
    {
        public static IEnumerable Power()
        {
            yield return "Hello world!";
        }
    }

Оператор yield из .Net Reflector - перенесенный в рялии C# и Visual Studio
class UserCollection
    {
        public static IEnumerable Power()
        {
            return new ClassPower(-2);
        }
 
        private sealed class ClassPower : IEnumerable<object>,  IEnumerator<object>, IEnumerator, IDisposable
        {
            // Поля.
            private int state;
            private object current;
            private int initialThreadId;
 
            // Конструктор.
            public ClassPower(int state)
            {
                this.state = state;
                this.initialThreadId = Thread.CurrentThread.ManagedThreadId;
            }
 
            //private bool IEnumerator.MoveNext() // Так в Рефлекторе
            bool IEnumerator.MoveNext()
            {
                switch (this.state)
                {
                    case 0:
                        this.state = -1;
                        this.current = "Hello world!";
                        this.state = 1;
                        return true;
 
                    case 1:
                        this.state = -1;
                        break;
                }
                return false;
            }
 
            IEnumerator<object> IEnumerable<object>.GetEnumerator()
            {
                if ((Thread.CurrentThread.ManagedThreadId == this.initialThreadId) && (this.state == -2))
                {
                   this.state = 0;
                   return this;
                }
                return new UserCollection.ClassPower(0);
            }
 
            IEnumerator IEnumerable.GetEnumerator()
            {
                // Так в Рефлекторе 
                //return this.System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator(); 
                
                return (this as IEnumerable<object>).GetEnumerator();
            }
 
            void IEnumerator.Reset()
            {
                throw new NotSupportedException();
            }
 
            void IDisposable.Dispose()
            {
            }
 
            // Свойства.
            object IEnumerator<object>.Current
            {
                get
                {
                    return this.current;
                }
            }
 
            object IEnumerator.Current
            {
                get
                {
                    return this.current;
                }
            }
        }
    }

Меня интересует строка и как ее комментирует автор
this.initialThreadId = Thread.CurrentThread.ManagedThreadId;

данная строка свидействует о синхронизации и доступа к этой коллекции как к разделяемому ресурсу.
Почему именно при работе с yield коллекция воспринимается как разделяемый ресурс и нужна вообще в принципе работа с потоками?
  • Вопрос задан
  • 211 просмотров
Решения вопроса 1
yarosroman
@yarosroman Куратор тега C#
C# the best
Не совсем, тут смотрится из какого потока вызывается и при необходимости возвращается другой перечислитель(Enumerator), просто если в нескольких потоках у вас идет перечисление коллекции, то в одном потоке вы не получите всю коллекцию, просто перед обращение к Current, может быть вызван метод MoveNext.

Enumerator лучше делать закрытым внутренним классом. В принципе даже не обязательно делать его реализацией интерфейса. достаточно просто метода MoveNext и свойства Current.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы