@@ -12,12 +12,13 @@ A library of queues that enable sending ordered tasks from nonisolated to asynch
12
12
Tasks sent from a nonisolated context to an asynchronous context in Swift Concurrency are inherently unordered. Consider the following test:
13
13
14
14
``` swift
15
- func testActorTaskOrdering () async {
15
+ @Test
16
+ func actorTaskOrdering () async {
16
17
actor Counter {
17
18
func incrementAndAssertCountEquals (_ expectedCount : Int ) {
18
19
count += 1
19
20
let incrementedCount = count
20
- XCTAssertEqual (incrementedCount, expectedCount) // often fails
21
+ #expect (incrementedCount == expectedCount) // often fails
21
22
}
22
23
23
24
private var count = 0
@@ -47,36 +48,35 @@ Use a `FIFOQueue` to execute asynchronous tasks enqueued from a nonisolated cont
47
48
48
49
A ` FIFOQueue ` can easily execute asynchronous tasks from a nonisolated context in FIFO order:
49
50
``` swift
50
- func testFIFOQueueOrdering () async {
51
+ @Test
52
+ func fIFOQueueOrdering () async {
51
53
actor Counter {
52
54
nonisolated
53
- func incrementAndAssertCountEquals (_ expectedCount : Int ) {
55
+ func incrementAndAssertCountEquals (_ expectedCount : Int ) -> Task< Void , Never > {
54
56
Task (on : queue) {
55
57
await self .increment ()
56
58
let incrementedCount = await self .count
57
- XCTAssertEqual (incrementedCount, expectedCount) // always succeeds
59
+ #expect (incrementedCount == expectedCount) // always succeeds
58
60
}
59
61
}
60
62
61
- func flushQueue () async {
62
- await Task (on : queue) {}.value
63
- }
64
-
65
63
func increment () {
66
64
count += 1
67
65
}
68
66
69
- var count = 0
70
-
67
+ private var count = 0
71
68
private let queue = FIFOQueue ()
72
69
}
73
70
74
71
let counter = Counter ()
72
+ var tasks = [Task< Void , Never > ]()
75
73
for iteration in 1 ... 100 {
76
- counter.incrementAndAssertCountEquals (iteration)
74
+ tasks. append ( counter.incrementAndAssertCountEquals (iteration) )
77
75
}
78
76
// Wait for all enqueued tasks to finish.
79
- await counter.flushQueue ()
77
+ for task in tasks {
78
+ _ = await task.value
79
+ }
80
80
}
81
81
```
82
82
@@ -92,36 +92,36 @@ An instance of an `ActorQueue` is designed to be utilized by a single `actor` in
92
92
93
93
An ` ActorQueue ` can easily enqueue tasks that execute on an actor’s isolated context from a nonisolated context in order:
94
94
``` swift
95
- func testActorQueueOrdering () async {
95
+ @Test
96
+ func actorQueueOrdering () async {
96
97
actor Counter {
97
98
init () {
98
99
// Adopting the execution context in `init` satisfies requirement #2 above.
99
100
queue.adoptExecutionContext (of : self )
100
101
}
101
102
102
103
nonisolated
103
- func incrementAndAssertCountEquals (_ expectedCount : Int ) {
104
- await Task (on : queue) { myself in
104
+ func incrementAndAssertCountEquals (_ expectedCount : Int ) -> Task< Void , Never > {
105
+ Task (on : queue) { myself in
105
106
myself.count += 1
106
- XCTAssertEqual (expectedCount, myself.count ) // always succeeds
107
+ #expect (expectedCount == myself.count ) // always succeeds
107
108
}
108
109
}
109
110
110
- func flushQueue () async {
111
- await Task (on : queue) {}.value
112
- }
113
-
114
111
private var count = 0
115
112
// Making the queue a private let constant satisfies requirement #1 above.
116
113
private let queue = ActorQueue< Counter> ()
117
114
}
118
115
119
116
let counter = Counter ()
117
+ var tasks = [Task< Void , Never > ]()
120
118
for iteration in 1 ... 100 {
121
- counter.incrementAndAssertCountEquals (iteration)
119
+ tasks. append ( counter.incrementAndAssertCountEquals (iteration) )
122
120
}
123
121
// Wait for all enqueued tasks to finish.
124
- await counter.flushQueue ()
122
+ for task in tasks {
123
+ _ = await task.value
124
+ }
125
125
}
126
126
```
127
127
@@ -132,35 +132,35 @@ Use `MainActor.queue` to send ordered asynchronous tasks to the `@MainActor`’s
132
132
A ` MainActor.queue ` can easily execute asynchronous tasks from a nonisolated context in FIFO order:
133
133
``` swift
134
134
@MainActor
135
- func testMainActorQueueOrdering () async {
135
+ @Test
136
+ func mainActorQueueOrdering () async {
136
137
@MainActor
137
138
final class Counter {
138
139
nonisolated
139
- func incrementAndAssertCountEquals (_ expectedCount : Int ) {
140
+ func incrementAndAssertCountEquals (_ expectedCount : Int ) -> Task< Void , Never > {
140
141
Task (on : MainActor.queue ) {
141
142
self .increment ()
142
143
let incrementedCount = self .count
143
- XCTAssertEqual (incrementedCount, expectedCount) // always succeeds
144
+ #expect (incrementedCount == expectedCount) // always succeeds
144
145
}
145
146
}
146
147
147
- func flushQueue () async {
148
- await Task (on : MainActor.queue ) { }.value
149
- }
150
-
151
148
func increment () {
152
149
count += 1
153
150
}
154
151
155
- var count = 0
152
+ private var count = 0
156
153
}
157
154
158
155
let counter = Counter ()
156
+ var tasks = [Task< Void , Never > ]()
159
157
for iteration in 1 ... 100 {
160
- counter.incrementAndAssertCountEquals (iteration)
158
+ tasks. append ( counter.incrementAndAssertCountEquals (iteration) )
161
159
}
162
160
// Wait for all enqueued tasks to finish.
163
- await counter.flushQueue ()
161
+ for task in tasks {
162
+ _ = await task.value
163
+ }
164
164
}
165
165
```
166
166
0 commit comments