Skip to content

Instantly share code, notes, and snippets.

@CarlosLanderas
Last active July 4, 2017 20:18
Show Gist options
  • Save CarlosLanderas/18918fd96621db58d4f9bac4389c7c76 to your computer and use it in GitHub Desktop.
Save CarlosLanderas/18918fd96621db58d4f9bac4389c7c76 to your computer and use it in GitHub Desktop.
Generalized Async Return Types in C# 7.0 sample code.
[AsyncMethodBuilder(typeof(AsyncCustomValueTaskMethodBuilder<>))]
[StructLayout(LayoutKind.Auto)]
public struct CustomValueTask<T>: IEquatable<CustomValueTask<T>>
{
internal readonly T _result;
internal readonly Task<T> _task;
public CustomValueTask(Task<T> task)
{
_task = task;
_result = default(T);
}
public CustomValueTask(T result)
{
_result = result;
_task = (Task<T>) null;
}
public Task<T> AsTask()
{
return _task ?? Task.FromResult<T>(_result);
}
public bool IsCompleted
{
get
{
if (this._task != null)
return this._task.IsCompleted;
return true;
}
}
public MyAwaiter<T> GetAwaiter()
{
return new MyAwaiter<T>(this);
}
public bool Equals(CustomValueTask<T> other)
{
if (this._task == null && other._task == null)
return EqualityComparer<T>.Default.Equals(this._result, other._result);
return _task == other._task;
}
[EditorBrowsable(EditorBrowsableState.Never)] // intended only for compiler consumption
public static AsyncValueTaskMethodBuilder<T> CreateAsyncMethodBuilder() => AsyncValueTaskMethodBuilder<T>.Create();
}
public struct MyAwaiter<T> : INotifyCompletion
{
private readonly CustomValueTask<T> _customValueTask;
public MyAwaiter(CustomValueTask<T> customValueTask)
{
_customValueTask = customValueTask;
}
public T GetResult()
{
if (_customValueTask._task != null)
return _customValueTask._task.GetAwaiter().GetResult();
return _customValueTask._result;
}
public bool IsCompleted => _customValueTask.IsCompleted;
public void OnCompleted(Action continuation)
{
_customValueTask.AsTask().ConfigureAwait(true).GetAwaiter().OnCompleted(continuation);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment