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
Use <xref:System.Threading.Tasks.Task> or <xref:System.Threading.Tasks.ValueTask> for methods without a result, and their generic forms for methods returning a result. Use <xref:System.Collections.Generic.IAsyncEnumerable`1>to [stream one call's results](async-enumerable-results.md) progressively. Don't use `void`, `async void`, or synchronous return types in grain contracts. A <xref:System.Threading.CancellationToken> can be included as a method parameter for cooperative cancellation. For the underlying C# model, see [Asynchronous programming](https://learn.microsoft.com/dotnet/csharp/asynchronous-programming/).
48
+
Use <xref:System.Threading.Tasks.Task> or <xref:System.Threading.Tasks.ValueTask> for methods without a result, and their generic forms for methods returning a result. Use <xref:System.Collections.Generic.IAsyncEnumerable`1>for [response streaming](response-streaming.md). Don't use `void`, `async void`, or synchronous return types in grain contracts. A <xref:System.Threading.CancellationToken> can be included as a method parameter for cooperative cancellation. For the underlying C# model, see [Asynchronous programming](https://learn.microsoft.com/dotnet/csharp/asynchronous-programming/).
49
49
50
50
Arguments, return values, and exceptions cross process boundaries. Make application data serializable by Orleans, normally using <xref:Orleans.GenerateSerializerAttribute> and stable <xref:Orleans.IdAttribute> values. Grain references are already serializable and can be passed in calls or stored as part of grain state.
51
51
@@ -146,7 +146,7 @@ See [Grain lifecycle](grain-lifecycle.md) for collection, lifecycle participatio
146
146
Most grains only need a contract, an implementation, a stable key, and regular request-response calls. Add specialized behavior only when the workload requires it:
147
147
148
148
-[Request scheduling and reentrancy](request-scheduling.md)
149
-
-[Stream grain results with IAsyncEnumerable](async-enumerable-results.md)
149
+
-[Response streaming with IAsyncEnumerable](response-streaming.md)
Copy file name to clipboardExpand all lines: docs/site/src/content/docs/grains/response-streaming.md
+16-16Lines changed: 16 additions & 16 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,17 +1,17 @@
1
1
---
2
-
title: Stream grain results with IAsyncEnumerable
3
-
description: Return IAsyncEnumerable<T> from an Orleans grain method to stream one call's results.
2
+
title: Response streaming with IAsyncEnumerable
3
+
description: Stream a grain call's response incrementally using IAsyncEnumerable<T>.
4
4
ms.date: 08/08/2026
5
5
ms.topic: concept-article
6
6
---
7
7
8
-
# Stream grain results with IAsyncEnumerable
8
+
# Response streaming with IAsyncEnumerable
9
9
10
-
A grain method can return <xref:System.Collections.Generic.IAsyncEnumerable`1>to deliver a sequence to one caller without materializing the full result first. The caller addresses a grain as for any other grain call, and then pulls results as they're produced.
10
+
**Response streaming** lets a grain method return <xref:System.Collections.Generic.IAsyncEnumerable`1>so one caller can consume a logically single grain call's response incrementally. The caller addresses a grain as for any other grain call, and then pulls results as they're produced.
11
11
12
-
Use this pattern for a query or command whose results are naturally incremental. It remains a single live grain call: it doesn't create a durable subscription, retain results, or multicast them to other consumers. For those capabilities, consider [Orleans streams](../streaming/index.md).
12
+
Use response streaming for a query or command whose results are naturally incremental. A response stream doesn't create a durable subscription, retain results, or multicast them to other consumers. For those capabilities, consider [Orleans Streams](../streaming/index.md).
13
13
14
-
## Define and implement a streaming method
14
+
## Define and implement a response-streaming method
15
15
16
16
Declare <xref:System.Collections.Generic.IAsyncEnumerable`1> directly on the grain interface. A cancellation token is optional, as with other grain methods:
17
17
@@ -21,15 +21,15 @@ An async iterator can produce each result with `yield return`. Apply <xref:Syste
Use `await foreach` to process each result. The remote enumeration starts when the caller requests the first element, not when the grain method returns the enumerable:
26
+
Use `await foreach` to process each result. The response stream starts when the caller requests the first element, not when the grain method returns the enumerable:
Leaving an `await foreach` loop disposes its enumerator, including when the loop exits with `break` or an exception.
31
31
32
-
## Control batching
32
+
## Control response batching
33
33
34
34
Orleans batches synchronously available elements to reduce network round trips, up to 100 elements by default. Use <xref:Orleans.Runtime.AsyncEnumerableExtensions.WithBatchSize*> to change that limit:
35
35
@@ -39,27 +39,27 @@ Call `WithBatchSize` directly on the value returned by the grain method and befo
39
39
40
40
Batching doesn't cause Orleans to read an unbounded number of elements ahead. The caller's next `MoveNextAsync` request drives production, and a batch contains only elements that become synchronously available, up to the configured limit.
41
41
42
-
## Cancel enumeration
42
+
## Cancel response streaming
43
43
44
44
Supply a token as a grain method argument, through `WithCancellation`, or both. Orleans links distinct tokens so cancellation of either stops the enumeration. Call `WithBatchSize` first when using both extensions:
Cancellation is cooperative and surfaces to the caller as <xref:System.OperationCanceledException>. The iterator must observe its token and pass it to cancellation-aware operations. See [Cancel Orleans grain calls](cancellation-tokens.md) for delivery and failure semantics.
48
+
Cancellation is cooperative and surfaces to the caller as <xref:System.OperationCanceledException>. The response-streaming method must observe its token and pass it to cancellation-aware operations. See [Cancel Orleans grain calls](cancellation-tokens.md) for delivery and failure semantics.
49
49
50
-
## Handle interrupted enumeration
50
+
## Handle an interrupted response stream
51
51
52
-
An exception thrown by the iterator propagates to the caller with its original exception type. The caller instead receives <xref:Orleans.Runtime.EnumerationAbortedException> if the grain deactivates during enumeration or the silo removes an enumerator which the caller left idle:
52
+
An exception thrown while producing the response stream propagates to the caller with its original exception type. The caller instead receives <xref:Orleans.Runtime.EnumerationAbortedException> if the grain deactivates during enumeration or the silo removes an enumerator which the caller left idle:
Idle-enumerator cleanup runs periodically using <xref:Orleans.Configuration.MessagingOptions.ResponseTimeout> as its interval. Don't hold an enumerator open while doing unrelated long-running work. If processing an element can take a long time, decouple that work from pulling the next element or use a messaging abstraction with a lifetime independent of one grain call.
57
57
58
-
## Choose between IAsyncEnumerable and Orleans streams
58
+
## Choose between response streaming and Orleans Streams
| Concern |Response streaming with `IAsyncEnumerable<T>`| Orleans Streams|
61
61
|---|---|---|
62
-
| Communication shape |One grain call, one producer, and one caller | Multicast pub/sub with independent producers and subscribers |
62
+
| Communication shape |Logically one grain call, one producer, and one caller | Multicast pub/sub with independent producers and subscribers |
63
63
| Lifetime | One live enumeration, ending on completion, disposal, cancellation, deactivation, or idle cleanup | Independent of any one grain call; subscriptions can survive activation changes |
64
64
| Flow control | Pull-based; `MoveNextAsync` drives production, with bounded batching | Provider-dependent delivery and buffering |
65
65
| Persistence and replay | None | Optional and provider-dependent |
Copy file name to clipboardExpand all lines: docs/site/src/content/docs/streaming/streams-why.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
---
2
2
title: Choose an Orleans messaging abstraction
3
-
description: Choose among grain calls, streamed grain results, observers, Orleans streams, and broadcast channels.
3
+
description: Choose among grain calls, response streaming, observers, Orleans streams, and broadcast channels.
4
4
ms.date: 08/08/2026
5
5
ms.topic: concept-article
6
6
---
@@ -12,7 +12,7 @@ Start from the relationship between sender and receiver and from the failure beh
12
12
| Use | Best fit | Important behavior |
13
13
|---|---|---|
14
14
| Invoke a known grain and await a result |**Grain call**| Addressed request/response with Orleans call semantics. The caller knows the target grain identity. |
15
-
| Return one grain call's results progressively |**`IAsyncEnumerable<T>` grain method**| Pull-based, single-caller enumeration. It isn't multicast, retained, or durable. |
15
+
| Return one grain call's results progressively |**Response streaming (`IAsyncEnumerable<T>`)**| Pull-based, single-caller enumeration. It isn't multicast, retained, or durable. |
16
16
| Push transient notifications from grains to a connected client |**Grain observer**| Ephemeral client callback. The application registers and removes observer references and handles disconnects. |
17
17
| Publish typed events to multiple independent subscriptions |**Orleans stream**| Multicast pub/sub. Provider selection controls durability, retries, ordering, and replay. Explicit subscriptions can survive activation changes. |
18
18
| Send best-effort notifications to grains selected from a channel identity |**Broadcast channel**| Implicit, nonpersistent fan-out. No queue, history, replay, or durable subscription registry. |
@@ -21,7 +21,7 @@ Start from the relationship between sender and receiver and from the failure beh
21
21
22
22
Use a grain call when the sender knows which grain owns the operation, needs a return value, or needs failure to propagate through the call. Grain calls make ownership and control flow explicit. Don't introduce a stream merely to avoid calling a known grain.
23
23
24
-
When one call produces many results, a grain method can return <xref:System.Collections.Generic.IAsyncEnumerable`1> so the caller processes them incrementally. See [Stream grain results with IAsyncEnumerable](../grains/async-enumerable-results.md).
24
+
Use **response streaming** when one call produces many results: the grain method returns <xref:System.Collections.Generic.IAsyncEnumerable`1> so the caller can process the response incrementally. See [Response streaming with IAsyncEnumerable](../grains/response-streaming.md).
0 commit comments