forked from parse-community/Parse-SDK-dotNET
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTaskCompletionSource.cs
109 lines (99 loc) · 4.08 KB
/
TaskCompletionSource.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace System.Threading.Tasks {
/// <summary>
/// Allows safe orchestration of a task's completion, preventing the consumer from prematurely
/// completing the task. Essentially, it represents the producer side of a <see cref="Tasks.Task{T}"/>,
/// providing access to the consumer side through the <see cref="TaskCompletionSource{T}.Task"/>
/// while isolating the Task's completion mechanisms from the consumer.
/// </summary>
/// <typeparam name="T">The type of the result of the Task being created.</typeparam>
public class TaskCompletionSource<T> {
/// <summary>
/// Constructs a new TaskCompletionSource.
/// </summary>
public TaskCompletionSource() {
Task = new Task<T>();
}
/// <summary>
/// Gets the task associated with this TaskCompletionSource.
/// </summary>
public Task<T> Task { get; private set; }
/// <summary>
/// If the task is not already complete, completes the task by setting the result.
/// </summary>
/// <param name="result">The result for the task.</param>
/// <returns><c>true</c> if the result was set successfully.</returns>
public bool TrySetResult(T result) {
return Task.TrySetResult(result);
}
/// <summary>
/// If the task is not already complete, completes the task by setting the exception.
/// </summary>
/// <param name="exception">The exception for the task.</param>
/// <returns><c>true</c> if the exception was set successfully.</returns>
public bool TrySetException(AggregateException exception) {
return Task.TrySetException(exception);
}
/// <summary>
/// If the task is not already complete, completes the task by setting the exception.
/// </summary>
/// <param name="exception">The exception for the task.</param>
/// <returns><c>true</c> if the exception was set successfully.</returns>
public bool TrySetException(Exception exception) {
var aggregate = exception as AggregateException;
if (aggregate != null) {
return Task.TrySetException(aggregate);
}
return Task.TrySetException(new AggregateException(new[] { exception }).Flatten());
}
/// <summary>
/// If the task is not already complete, cancels the task.
/// </summary>
/// <returns><c>true</c> if the task was successfully cancelled.</returns>
public bool TrySetCanceled() {
return Task.TrySetCanceled();
}
/// <summary>
/// Completes the task by setting the result. Throws an <see cref="InvalidOperationException"/>
/// if the task is already complete.
/// </summary>
/// <param name="result">The result for the task.</param>
public void SetResult(T result) {
if (!TrySetResult(result)) {
throw new InvalidOperationException("Cannot set the result of a completed task.");
}
}
/// <summary>
/// Completes the task by setting the exception. Throws an
/// <see cref="InvalidOperationException"/> if the task is already complete.
/// </summary>
/// <param name="exception">The exception for the task.</param>
public void SetException(AggregateException exception) {
if (!TrySetException(exception)) {
throw new InvalidOperationException("Cannot set the exception of a completed task.");
}
}
/// <summary>
/// Completes the task by setting the exception. Throws an
/// <see cref="InvalidOperationException"/> if the task is already complete.
/// </summary>
/// <param name="exception">The exception for the task.</param>
public void SetException(Exception exception) {
if (!TrySetException(exception)) {
throw new InvalidOperationException("Cannot set the exception of a completed task.");
}
}
/// <summary>
/// Cancels the task. Throws an <see cref="InvalidOperationException"/> if the task is
/// already complete.
/// </summary>
public void SetCanceled() {
if (!TrySetCanceled()) {
throw new InvalidOperationException("Cannot cancel a completed task.");
}
}
}
}