В зависимости от деталей реализации будущего вы можете пойти так:
AsyncResult
- это просто оболочка в Future, которая реализует правильный интерфейс и присоединяется к обратным вызовам.
internal class AsyncResult<T> : IAsyncResult
{
private ManualResetEvent _manualResetEvent = new ManualResetEvent(false);
public object AsyncState => null;
public WaitHandle AsyncWaitHandle => _manualResetEvent;
public bool CompletedSynchronously => false;
public bool IsCompleted { get; private set; }
public T Result { get; private set; }
public Exception Error { get; private set; }
public AsyncResult(IFuture<T> future)
{
future.OnSuccess(result =>
{
Result = result;
IsCompleted = true;
_manualResetEvent.Set();
});
future.OnError(() =>
{
Error = future.error;
IsCompleted = true;
_manualResetEvent.Set();
});
}
}
метод, который преобразует Future
в Task
, как вы хотели:
public static class FutureExtensions
{
public static Task<T> ToAsync<T>(this IFuture<T> future)
{
var asyncResult = new AsyncResult<T>(future);
var task = Task.Factory.FromAsync(asyncResult, x =>
{
var ar = (AsyncResult<T>)x;
if (ar.Error != null)
{
throw new AggregateException("Task failed.", ar.Error);
}
return ar.Result;
});
return task;
}
}
и пример использования:
internal static class Program
{
public static async Task Main()
{
var future = new Future(success: true);
var result = await future.ToAsync();
Console.WriteLine(result);
var future2 = new Future(success: false);
try
{
var result2 = await future2.ToAsync();
}
catch (AggregateException e)
{
Console.WriteLine(e.InnerException.Message);
}
}
}