Browse Source

Add types IYielder, IAwaitable, and IAwait; add support for creating IEnumerable from Action<IYielder>.

malayeri 12 năm trước cách đây
mục cha
commit
a5ec5e8f0c

+ 11 - 0
Ix/NET/Source/System.Interactive/EnumerableEx.Creation.cs

@@ -20,6 +20,17 @@ namespace System.Linq
             return new AnonymousEnumerable<TResult>(getEnumerator);
         }
 
+#if HAS_AWAIT
+        public static IEnumerable<T> Create<T>(Action<IYielder<T>> create)
+        {
+            if (create == null)
+                throw new ArgumentNullException("create");
+
+            foreach (var x in new Yielder<T>(create))
+                yield return x;
+        }
+#endif
+
         class AnonymousEnumerable<TResult> : IEnumerable<TResult>
         {
             private readonly Func<IEnumerator<TResult>> _getEnumerator;

+ 23 - 0
Ix/NET/Source/System.Interactive/IAwaitable.cs

@@ -0,0 +1,23 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+#if HAS_AWAIT
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace System.Linq
+{
+    public interface IAwaitable
+    {
+        IAwaiter GetAwaiter();
+    }
+
+    public interface IAwaiter : ICriticalNotifyCompletion
+    {
+        bool IsCompleted { get; }
+        void GetResult();
+    }
+}
+#endif

+ 100 - 0
Ix/NET/Source/System.Interactive/IYielder.cs

@@ -0,0 +1,100 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
+using System;
+using System.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+#if HAS_AWAIT
+namespace System.Linq
+{
+    public interface IYielder<in T>
+    {
+        IAwaitable Return(T value);
+        IAwaitable Break();
+    }
+
+    class Yielder<T> : IYielder<T>, IAwaitable, IAwaiter, ICriticalNotifyCompletion
+    {
+        private readonly Action<Yielder<T>> _create;
+        private bool _running;
+        private bool _hasValue;
+        private T _value;
+        private bool _stopped;
+        private Action _continuation;
+
+        public Yielder(Action<Yielder<T>> create)
+        {
+            _create = create;
+        }
+
+        public IAwaitable Return(T value)
+        {
+            _hasValue = true;
+            _value = value;
+            return this;
+        }
+
+        public IAwaitable Break()
+        {
+            _stopped = true;
+            return this;
+        }
+
+        public Yielder<T> GetEnumerator()
+        {
+            return this;
+        }
+
+        public bool MoveNext()
+        {
+            if (!_running)
+            {
+                _running = true;
+                _create(this);
+            }
+            else
+            {
+                _hasValue = false;
+                _continuation();
+            }
+
+            return !_stopped && _hasValue;
+        }
+
+        public T Current
+        {
+            get
+            {
+                return _value;
+            }
+        }
+
+        public void Reset()
+        {
+            throw new NotSupportedException();
+        }
+
+        public IAwaiter GetAwaiter()
+        {
+            return this;
+        }
+
+        public bool IsCompleted
+        {
+            get { return false; }
+        }
+
+        public void UnsafeOnCompleted(Action continuation)
+        {
+            _continuation = continuation;
+        }
+
+        public void GetResult() { }
+
+
+        public void OnCompleted(Action continuation)
+        {
+            _continuation = continuation;
+        }
+    }
+}
+#endif