Skip to content

Instantly share code, notes, and snippets.

@atifaziz
Created March 26, 2014 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save atifaziz/9782440 to your computer and use it in GitHub Desktop.
Save atifaziz/9782440 to your computer and use it in GitHub Desktop.
Alternate IYielder Rx with exception handling
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Linq;
using System.Runtime.ExceptionServices;
using System.Security;
#if HAS_AWAIT
namespace System.Linq
{
public interface IYielder<in T>
{
IAwaitable Return(T value);
IAwaitable Break();
IAwaitable Throw(Exception error);
}
sealed class Yielder<T> : IYielder<T>, IAwaitable, IAwaiter
{
private readonly Action<IYielder<T>> _create;
private bool _running;
private bool _hasValue;
private ExceptionDispatchInfo _error;
private bool _stopped;
private Action _continuation;
public Yielder(Action<IYielder<T>> create)
{
_create = create;
}
public IAwaitable Return(T value)
{
_hasValue = true;
Current = value;
return this;
}
public IAwaitable Break()
{
_stopped = true;
return this;
}
public IAwaitable Throw(Exception error)
{
if (_error != null) throw new InvalidOperationException();
_error = ExceptionDispatchInfo.Capture(error);
return this;
}
public Yielder<T> GetEnumerator()
{
return this;
}
public bool MoveNext()
{
if (!_running)
{
_running = true;
_create(this);
}
else
{
_hasValue = false;
_continuation();
}
if (_error != null)
_error.Throw();
return !_stopped && _hasValue;
}
public T Current { get; private set; }
public void Reset()
{
throw new NotSupportedException();
}
public IAwaiter GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get { return false; }
}
public void GetResult() { }
[SecurityCritical]
public void UnsafeOnCompleted(Action continuation)
{
_continuation = continuation;
}
public void OnCompleted(Action continuation)
{
_continuation = continuation;
}
}
}
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment