TaskExtensions.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. namespace Caliburn.Micro.Core {
  2. using System;
  3. using System.Threading.Tasks;
  4. /// <summary>
  5. /// Extension methods to bring <see cref="System.Threading.Tasks.Task"/> and <see cref="Caliburn.Micro.IResult"/> together.
  6. /// </summary>
  7. public static class TaskExtensions {
  8. /// <summary>
  9. /// Executes an <see cref="Caliburn.Micro.IResult"/> asynchronous.
  10. /// </summary>
  11. /// <param name="result">The coroutine to execute.</param>
  12. /// <param name="context">The context to execute the coroutine within.</param>
  13. /// <returns>A task that represents the asynchronous coroutine.</returns>
  14. public static Task ExecuteAsync(this IResult result, CoroutineExecutionContext context = null) {
  15. return InternalExecuteAsync<object>(result, context);
  16. }
  17. /// <summary>
  18. /// Executes an <see cref="Caliburn.Micro.IResult&lt;TResult&gt;"/> asynchronous.
  19. /// </summary>
  20. /// <typeparam name="TResult">The type of the result.</typeparam>
  21. /// <param name="result">The coroutine to execute.</param>
  22. /// <param name="context">The context to execute the coroutine within.</param>
  23. /// <returns>A task that represents the asynchronous coroutine.</returns>
  24. public static Task<TResult> ExecuteAsync<TResult>(this IResult<TResult> result,
  25. CoroutineExecutionContext context = null) {
  26. return InternalExecuteAsync<TResult>(result, context);
  27. }
  28. static Task<TResult> InternalExecuteAsync<TResult>(IResult result, CoroutineExecutionContext context) {
  29. var taskSource = new TaskCompletionSource<TResult>();
  30. EventHandler<ResultCompletionEventArgs> completed = null;
  31. completed = (s, e) => {
  32. result.Completed -= completed;
  33. if (e.Error != null)
  34. taskSource.SetException(e.Error);
  35. else if (e.WasCancelled)
  36. taskSource.SetCanceled();
  37. else {
  38. var rr = result as IResult<TResult>;
  39. taskSource.SetResult(rr != null ? rr.Result : default(TResult));
  40. }
  41. };
  42. try {
  43. IoC.BuildUp(result);
  44. result.Completed += completed;
  45. result.Execute(context ?? new CoroutineExecutionContext());
  46. }
  47. catch (Exception ex) {
  48. result.Completed -= completed;
  49. taskSource.SetException(ex);
  50. }
  51. return taskSource.Task;
  52. }
  53. /// <summary>
  54. /// Encapsulates a task inside a couroutine.
  55. /// </summary>
  56. /// <param name="task">The task.</param>
  57. /// <returns>The coroutine that encapsulates the task.</returns>
  58. public static TaskResult AsResult(this Task task) {
  59. return new TaskResult(task);
  60. }
  61. /// <summary>
  62. /// Encapsulates a task inside a couroutine.
  63. /// </summary>
  64. /// <typeparam name="TResult">The type of the result.</typeparam>
  65. /// <param name="task">The task.</param>
  66. /// <returns>The coroutine that encapsulates the task.</returns>
  67. public static TaskResult<TResult> AsResult<TResult>(this Task<TResult> task) {
  68. return new TaskResult<TResult>(task);
  69. }
  70. }
  71. }