@@ -15,6 +15,37 @@ import Swift
15
15
16
16
// ==== Task Cancellation ------------------------------------------------------
17
17
18
+ /// Execute an operation with cancellation handler which will immediately be
19
+ /// invoked if the current task is cancelled.
20
+ ///
21
+ /// This differs from the operation cooperatively checking for cancellation
22
+ /// and reacting to it in that the cancellation handler is _always_ and
23
+ /// _immediately_ invoked when the task is cancelled. For example, even if the
24
+ /// operation is running code which never checks for cancellation, a cancellation
25
+ /// handler still would run and give us a chance to run some cleanup code.
26
+ ///
27
+ /// Does not check for cancellation, and always executes the passed `operation`.
28
+ ///
29
+ /// This function returns instantly and will never suspend.
30
+ @available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
31
+ public func withTaskCancellationHandler< T> (
32
+ handler: @Sendable ( ) -> ( ) ,
33
+ operation: ( ) async throws -> T
34
+ ) async rethrows -> T {
35
+ let task = Builtin . getCurrentAsyncTask ( )
36
+
37
+ guard !_taskIsCancelled( task) else {
38
+ // If the current task is already cancelled, run the handler immediately.
39
+ handler ( )
40
+ return try await operation ( )
41
+ }
42
+
43
+ let record = _taskAddCancellationHandler ( handler: handler)
44
+ defer { _taskRemoveCancellationHandler ( record: record) }
45
+
46
+ return try await operation ( )
47
+ }
48
+
18
49
@available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
19
50
extension Task {
20
51
@@ -57,34 +88,12 @@ extension Task {
57
88
}
58
89
}
59
90
60
- /// Execute an operation with cancellation handler which will immediately be
61
- /// invoked if the current task is cancelled.
62
- ///
63
- /// This differs from the operation cooperatively checking for cancellation
64
- /// and reacting to it in that the cancellation handler is _always_ and
65
- /// _immediately_ invoked when the task is cancelled. For example, even if the
66
- /// operation is running code which never checks for cancellation, a cancellation
67
- /// handler still would run and give us a chance to run some cleanup code.
68
- ///
69
- /// Does not check for cancellation, and always executes the passed `operation`.
70
- ///
71
- /// This function returns instantly and will never suspend.
91
+ @available ( * , deprecated, message: " `Task.withCancellationHandler` has been replaced by `withTaskCancellationHandler` and will be removed shortly. " )
72
92
public static func withCancellationHandler< T> (
73
93
handler: @Sendable ( ) -> ( ) ,
74
94
operation: ( ) async throws -> T
75
95
) async rethrows -> T {
76
- let task = Builtin . getCurrentAsyncTask ( )
77
-
78
- guard !_taskIsCancelled( task) else {
79
- // If the current task is already cancelled, run the handler immediately.
80
- handler ( )
81
- return try await operation ( )
82
- }
83
-
84
- let record = _taskAddCancellationHandler ( handler: handler)
85
- defer { _taskRemoveCancellationHandler ( record: record) }
86
-
87
- return try await operation ( )
96
+ try await withTaskCancellationHandler ( handler: handler, operation: operation)
88
97
}
89
98
90
99
/// The default cancellation thrown when a task is cancelled.
@@ -95,7 +104,6 @@ extension Task {
95
104
// no extra information, cancellation is intended to be light-weight
96
105
public init ( ) { }
97
106
}
98
-
99
107
}
100
108
101
109
@available ( macOS 9999 , iOS 9999 , watchOS 9999 , tvOS 9999 , * )
0 commit comments