using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace Prise.Proxy
{
///
/// This is a non-generic TaskCompletionSource
/// It allows you to set a type via its constructor
///
public class TaskCompletionSource
{
private readonly Type type;
private readonly object taskCompletionSource;
public TaskCompletionSource(Type type)
{
this.type = type;
this.taskCompletionSource = typeof(TaskCompletionSource<>)
.MakeGenericType(type)
.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0]
.Invoke(null);
}
public bool TrySetCanceled()
{
var trySetCanceled = taskCompletionSource.GetType().GetMethod("TrySetCanceled");
return (bool)trySetCanceled.Invoke(this.taskCompletionSource, null);
}
public bool TrySetException(Exception ex)
{
var trySetException = taskCompletionSource.GetType()
.GetMethods()
.First(m => m.Name == "TrySetException" && m.GetParameters().First().ParameterType == typeof(IEnumerable));
return (bool)trySetException.Invoke(this.taskCompletionSource, new[] { new[] { ex } });
}
public bool TrySetResult(object result)
{
var trySetResult = taskCompletionSource.GetType().GetMethod("TrySetResult");
return (bool)trySetResult.Invoke(this.taskCompletionSource, new[] { result });
}
public Task Task
{
get
{
var taskProperty = taskCompletionSource.GetType().GetProperty("Task");
return taskProperty.GetValue(this.taskCompletionSource) as Task;
}
}
}
}