Sic.Framework/MECF.Framework.UI.Client/Caliburn.Micro/Core/TaskExtensions.cs

81 lines
3.3 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
namespace Caliburn.Micro.Core {
using System;
using System.Threading.Tasks;
/// <summary>
/// Extension methods to bring <see cref="System.Threading.Tasks.Task"/> and <see cref="IResult"/> together.
2023-04-13 11:51:03 +08:00
/// </summary>
public static class TaskExtensions {
/// <summary>
/// Executes an <see cref="IResult"/> asynchronous.
2023-04-13 11:51:03 +08:00
/// </summary>
/// <param name="result">The coroutine to execute.</param>
/// <param name="context">The context to execute the coroutine within.</param>
/// <returns>A task that represents the asynchronous coroutine.</returns>
public static Task ExecuteAsync(this IResult result, CoroutineExecutionContext context = null) {
return InternalExecuteAsync<object>(result, context);
}
/// <summary>
/// Executes an <see cref="IResult"/> asynchronous.
2023-04-13 11:51:03 +08:00
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="result">The coroutine to execute.</param>
/// <param name="context">The context to execute the coroutine within.</param>
/// <returns>A task that represents the asynchronous coroutine.</returns>
public static Task<TResult> ExecuteAsync<TResult>(this IResult<TResult> result,
CoroutineExecutionContext context = null) {
return InternalExecuteAsync<TResult>(result, context);
}
static Task<TResult> InternalExecuteAsync<TResult>(IResult result, CoroutineExecutionContext context) {
var taskSource = new TaskCompletionSource<TResult>();
EventHandler<ResultCompletionEventArgs> completed = null;
completed = (s, e) => {
result.Completed -= completed;
if (e.Error != null)
taskSource.SetException(e.Error);
else if (e.WasCancelled)
taskSource.SetCanceled();
else {
var rr = result as IResult<TResult>;
taskSource.SetResult(rr != null ? rr.Result : default(TResult));
}
};
try {
IoC.BuildUp(result);
result.Completed += completed;
result.Execute(context ?? new CoroutineExecutionContext());
}
catch (Exception ex) {
result.Completed -= completed;
taskSource.SetException(ex);
}
return taskSource.Task;
}
/// <summary>
/// Encapsulates a task inside a couroutine.
/// </summary>
/// <param name="task">The task.</param>
/// <returns>The coroutine that encapsulates the task.</returns>
public static TaskResult AsResult(this Task task) {
return new TaskResult(task);
}
/// <summary>
/// Encapsulates a task inside a couroutine.
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <param name="task">The task.</param>
/// <returns>The coroutine that encapsulates the task.</returns>
public static TaskResult<TResult> AsResult<TResult>(this Task<TResult> task) {
return new TaskResult<TResult>(task);
}
}
}