You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-[Further reading on `IAsyncEnumerable`](#further-reading-on-iasyncenumerable)
33
34
-[Further reading on resumable state machines](#further-reading-on-resumable-state-machines)
34
35
-[Further reading on computation expressions](#further-reading-on-computation-expressions)
35
-
-[Building & testing](#building--testing)
36
+
-[Building \& testing](#building--testing)
36
37
-[Prerequisites](#prerequisites)
37
38
-[Build the solution](#build-the-solution)
38
39
-[Run the tests](#run-the-tests)
@@ -163,6 +164,33 @@ let feedFromTwitter user pwd = taskSeq {
163
164
}
164
165
```
165
166
167
+
## Choosing between `AsyncSeq` and `TaskSeq`
168
+
169
+
The [`AsyncSeq`][11] and `TaskSeq` library both operate on asynchronous sequences, but there are a few fundamental differences, most notably that the former _does not_ implement `IAsyncEnumerable<'T>`, but has its own same-named, but differently behaving type. Another core difference is that `TaskSeq` uses `ValueTasks` for the asynchronous computations, and `AsyncSeq` uses F#'s `Async<'T>`.
|**Support `let!`**| All `task`-like: `Async<'T>`, `ValueTask<'T>` and `ValueTask`, `Task<'T>` and `Task` or anything with `GetAwaiter()`|`Async<'T>` only |
180
+
|**Support `do!`**|`Async<unit>`, `Task<unit>` and `Task`, `ValueTask<unit>` and `ValueTask`|`Async<unit>` only |
181
+
|**Support `yield!`**|`IAsyncEnumerable<'T>`, `AsyncSeq`, any sequence |`AsyncSeq`|
182
+
|**Support `for`**|`IAsyncEnumerable<'T>`, `AsyncSeq`, any sequence |`AsyncSeq` any sequence |
183
+
|**Behavior with `yield`**| Zero allocations, no `Task` or even `ValueTask` created | Allocated, an F# `Async` wrapped in a singleton `AsyncSeq`|
184
+
|**Conversion to other**|`TaskSeq.toAsyncSeq`|`AsyncSeq.toAsyncEnum`|
185
+
|**Conversion from other**| Implicit (yield!) or `TaskSeq.ofAsyncSeq`|`AsyncSeq.ofAsyncEnum`|
186
+
|**Recursion in `yield!`**| No (requires F# support, upcoming) | Yes |
|**Cancellation**| Implicit token governing iteration | Implicit token passed to each subtask |
191
+
|**Performance**| Very high, negligible allocations | Slower, more allocations, due to using `async`|
192
+
|**Parallelism**| Possible with ChildTask, support will follow | Supported explicitly |
193
+
166
194
## Status & planning
167
195
168
196
This project has stable features currently, but before we go full "version one", we'd like to complete the surface area. This section covers the status of that, with a full list of implmented functions below. Here's the short list:
@@ -330,12 +358,6 @@ The following is the progress report:
330
358
331
359
## More information
332
360
333
-
### The AsyncSeq library
334
-
335
-
If you're looking to use `IAsyncEnumerable` with `async` and not `task`, the existing [`AsyncSeq`][11] library already provides excellent coverage of that use case. While `TaskSeq` is intended to interoperate with `async` as `task` does, it's not intended to provide an `AsyncSeq` type (at least not yet).
336
-
337
-
In short, if your application is using `Async` (and the parallelism features stemming from that), consider using the `AsyncSeq` library instead.
338
-
339
361
### Further reading on `IAsyncEnumerable`
340
362
341
363
- A good C#-based introduction [can be found in this blog][8].
0 commit comments