TaskExt.cs 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the Apache 2.0 License.
  3. // See the LICENSE file in the project root for more information.
  4. using System.Collections.Generic;
  5. namespace System.Threading.Tasks
  6. {
  7. static class TaskExt
  8. {
  9. public static readonly Task<bool> True = Task.FromResult(true);
  10. public static readonly Task<bool> False = Task.FromResult(false);
  11. public static Task<T> Throw<T>(Exception exception)
  12. {
  13. var tcs = new TaskCompletionSource<T>();
  14. tcs.TrySetException(exception);
  15. return tcs.Task;
  16. }
  17. public static Task<V> Zip<T, U, V>(this Task<T> t1, Task<U> t2, Func<T, U, V> f)
  18. {
  19. var tcs = new TaskCompletionSource<V>();
  20. var i = 2;
  21. var complete = new Action<Task>(t =>
  22. {
  23. if (Interlocked.Decrement(ref i) == 0)
  24. {
  25. var exs = new List<Exception>();
  26. if (t1.IsFaulted)
  27. exs.Add(t1.Exception);
  28. if (t2.IsFaulted)
  29. exs.Add(t2.Exception);
  30. if (exs.Count > 0)
  31. tcs.TrySetException(exs);
  32. else if (t1.IsCanceled || t2.IsCanceled)
  33. tcs.TrySetCanceled();
  34. else
  35. {
  36. var res = default(V);
  37. try
  38. {
  39. res = f(t1.Result, t2.Result);
  40. }
  41. catch (Exception ex)
  42. {
  43. tcs.TrySetException(ex);
  44. return;
  45. }
  46. tcs.TrySetResult(res);
  47. }
  48. }
  49. });
  50. t1.ContinueWith(complete);
  51. t2.ContinueWith(complete);
  52. return tcs.Task;
  53. }
  54. }
  55. }