<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Tutorial: Dapr.Messaging by example on Dapr Docs</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/</link><description>Recent content in Tutorial: Dapr.Messaging by example on Dapr Docs</description><generator>Hugo</generator><language>en</language><atom:link href="https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/index.xml" rel="self" type="application/rss+xml"/><item><title>Part 1: Publish events with Dapr.Messaging</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-publishing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-publishing/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/01-Publishing">publishing example&lt;/a> introduces &lt;code>IDaprPublishSubscribeClient&lt;/code>, the publishing API in &lt;code>Dapr.Messaging&lt;/code>.&lt;/p>
&lt;h2 id="register-the-client">Register the client&lt;/h2>
&lt;p>&lt;code>AddDaprMessaging()&lt;/code> registers the client with dependency injection:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">builder&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">WebApplication&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CreateBuilder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Services&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddDaprMessaging&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">app&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Build&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Inject &lt;code>IDaprPublishSubscribeClient&lt;/code> into an endpoint, service, or background worker. The client is intended to be reused rather than created for every message.&lt;/p>
&lt;h2 id="publish-typed-events">Publish typed events&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">MapPost&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;/orders&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kd">async&lt;/span> &lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OrderPlaced&lt;/span> &lt;span class="n">order&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">IDaprPublishSubscribeClient&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">await&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">PublishEventAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;pubsub&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;orders&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">order&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Results&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Accepted&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">$&amp;#34;/orders/{order.OrderId}&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Typed payloads are serialized as JSON and published as Dapr CloudEvents. Pass the request cancellation token through the SDK call.&lt;/p></description></item><item><title>Part 2: Declarative streaming subscriptions</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-streaming/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-streaming/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/02-Streaming">streaming example&lt;/a> shows the recommended declarative subscription model for fixed topics.&lt;/p>
&lt;h2 id="define-a-handler">Define a handler&lt;/h2>
&lt;p>Implement &lt;code>ITopicHandler&amp;lt;TMessage&amp;gt;&lt;/code> and decorate the handler with &lt;code>DaprTopic&lt;/code>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopic(&amp;#34;pubsub&amp;#34;, &amp;#34;orders&amp;#34;, Delivery = DeliveryMode.Streaming)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span> &lt;span class="kd">sealed&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">OrderProcessingHandler&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ITopicHandler&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">OrderPlaced&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">HandleAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">OrderPlaced&lt;/span> &lt;span class="n">order&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopicContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">order&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Quantity&lt;/span> &lt;span class="p">&amp;lt;=&lt;/span> &lt;span class="m">0&lt;/span> &lt;span class="p">||&lt;/span> &lt;span class="kt">string&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">IsNullOrWhiteSpace&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">order&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ItemSku&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Drop&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">order&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">ItemSku&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">StartsWith&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;RETRY-&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">StringComparison&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">OrdinalIgnoreCase&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Retry&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Success&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>Success&lt;/code> acknowledges the message, &lt;code>Retry&lt;/code> requests redelivery for a transient failure, and &lt;code>Drop&lt;/code> rejects an invalid or poison message. The handler also receives &lt;code>TopicContext&lt;/code>, which contains the pub/sub name, topic, message ID, headers, and metadata.&lt;/p></description></item><item><title>Part 3: Content-based routing and dead-letter topics</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-routing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-routing/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/03-RoutingAndDeadLetter">routing example&lt;/a> uses multiple generated subscriptions to route shipments and handle rejected messages.&lt;/p>
&lt;h2 id="add-cel-matching-rules">Add CEL matching rules&lt;/h2>
&lt;p>&lt;code>Match&lt;/code> is evaluated against the CloudEvent. &lt;code>Priority&lt;/code> controls rule ordering, with lower values evaluated first:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopic(
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;pubsub&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;express-shipments&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> Match = &amp;#34;event.data.priorityTier == &amp;#39;express&amp;#39;&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> Priority = 1,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> DeadLetterTopic = &amp;#34;deadletter-shipments&amp;#34;)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopicMetadata(&amp;#34;routingType&amp;#34;, &amp;#34;express-tier&amp;#34;)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span> &lt;span class="kd">sealed&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">ExpressShippingHandler&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ITopicHandler&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">ShipmentPackage&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">HandleAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ShipmentPackage&lt;/span> &lt;span class="n">shipment&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopicContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">shipment&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WeightKg&lt;/span> &lt;span class="p">&amp;lt;=&lt;/span> &lt;span class="m">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">?&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Drop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Success&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The example adds an international rule using &lt;code>event.data.destinationCountry != 'US'&lt;/code> and a priority-10 catch-all handler for standard domestic shipments. &lt;code>DaprTopicMetadata&lt;/code> adds custom key-value data to the generated subscription manifest.&lt;/p></description></item><item><title>Part 4: Bulk subscriptions</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-bulk/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-bulk/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/04-BulkSubscribe">bulk subscription example&lt;/a> combines bulk publishing with a subscription configured for high-throughput ingestion.&lt;/p>
&lt;h2 id="configure-batching">Configure batching&lt;/h2>
&lt;p>Set &lt;code>BulkSubscribe&lt;/code> and its limits on the topic attribute:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopic(
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;pubsub&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;telemetry&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> BulkSubscribe = true,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> MaxMessagesCount = 50,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> MaxAwaitDurationMs = 500)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span> &lt;span class="kd">sealed&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">TelemetryBulkHandler&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ITopicHandler&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">DeviceTelemetry&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">HandleAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DeviceTelemetry&lt;/span> &lt;span class="n">reading&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopicContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="n">reading&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">TemperatureCelsius&lt;/span> &lt;span class="p">&amp;lt;&lt;/span> &lt;span class="p">-&lt;/span>&lt;span class="m">273.15&lt;/span> &lt;span class="p">||&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">reading&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">HumidityPercent&lt;/span> &lt;span class="k">is&lt;/span> &lt;span class="p">&amp;lt;&lt;/span> &lt;span class="m">0&lt;/span> &lt;span class="n">or&lt;/span> &lt;span class="p">&amp;gt;&lt;/span> &lt;span class="m">100&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Drop&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Success&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>MaxMessagesCount&lt;/code> bounds the batch size and &lt;code>MaxAwaitDurationMs&lt;/code> bounds how long Dapr waits before delivering a partial batch. Choose values based on throughput, latency, and broker behavior. The handler remains responsible for the individual message decision.&lt;/p></description></item><item><title>Part 5: gRPC AppCallback push subscriptions</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-appcallback/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-appcallback/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/05-AppCallbackPush">AppCallback example&lt;/a> uses &lt;code>DeliveryMode.Programmatic&lt;/code> for sidecar-to-application gRPC push.&lt;/p>
&lt;h2 id="define-a-programmatic-subscriber">Define a programmatic subscriber&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopic(&amp;#34;pubsub&amp;#34;, &amp;#34;payments&amp;#34;, Delivery = DeliveryMode.Programmatic)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span> &lt;span class="kd">sealed&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">PaymentProcessingHandler&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ITopicHandler&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">PaymentReceived&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">HandleAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PaymentReceived&lt;/span> &lt;span class="n">payment&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopicContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">payment&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Amount&lt;/span> &lt;span class="p">&amp;lt;=&lt;/span> &lt;span class="m">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">?&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Drop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Success&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>In this mode Dapr initiates the gRPC call to the application&amp;rsquo;s AppCallback service. Unlike streaming subscriptions, the app must expose a reachable gRPC port.&lt;/p>
&lt;h2 id="map-the-generated-endpoint">Map the generated endpoint&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">builder&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">WebApplication&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CreateBuilder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Services&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddDaprMessaging&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">app&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Build&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">MapDaprMessaging&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Run&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>MapDaprMessaging()&lt;/code> exposes the generated AppCallback gRPC service used by the sidecar
to list subscriptions and deliver events. Run the application with an app port and gRPC
protocol, for example:&lt;/p></description></item><item><title>Part 6: HTTP push subscriptions</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-http/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-http/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/06-HttpSubscription">HTTP subscription example&lt;/a> shows &lt;code>DeliveryMode.Http&lt;/code> for applications that use normal HTTP ingress or reverse proxies.&lt;/p>
&lt;h2 id="define-a-routed-handler">Define a routed handler&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="na">[DaprTopic(
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;pubsub&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> &amp;#34;invoices&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> Delivery = DeliveryMode.Http,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="na"> Route = &amp;#34;api/events/invoices&amp;#34;)]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">public&lt;/span> &lt;span class="kd">sealed&lt;/span> &lt;span class="k">class&lt;/span> &lt;span class="nc">InvoiceProcessingHandler&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="n">ITopicHandler&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">InvoiceGenerated&lt;/span>&lt;span class="p">&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kd">public&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">&amp;gt;&lt;/span> &lt;span class="n">HandleAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InvoiceGenerated&lt;/span> &lt;span class="n">invoice&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TopicContext&lt;/span> &lt;span class="n">context&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CancellationToken&lt;/span> &lt;span class="n">cancellationToken&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromResult&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">invoice&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">TotalAmount&lt;/span> &lt;span class="p">&amp;lt;=&lt;/span> &lt;span class="m">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">?&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Drop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">:&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Success&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="map-the-generated-routes">Map the generated routes&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">builder&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">WebApplication&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CreateBuilder&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">args&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Services&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddDaprMessaging&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">app&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Build&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">MapDaprMessaging&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Run&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The generated mapping exposes &lt;code>GET /dapr/subscribe&lt;/code> for Dapr to discover subscriptions and maps &lt;code>POST /api/events/invoices&lt;/code> for the topic&amp;rsquo;s CloudEvents. The route is generated from the &lt;code>Route&lt;/code> property; it does not need a separate controller or action.&lt;/p></description></item><item><title>Part 7: Dynamic streaming subscriptions</title><link>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-dynamic/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://dapr.website.cncfstack.com/developing-applications/sdks/dotnet/dotnet-messaging/tutorial/dotnet-messaging-tutorial-dynamic/</guid><description>&lt;p>The &lt;a href="https://github.com/dapr/dotnet-sdk/tree/master/examples/Messaging/07-DynamicStreaming">dynamic streaming example&lt;/a> uses &lt;code>SubscribeAsync&lt;/code> when topics or subscription lifetime cannot be fixed at compile time.&lt;/p>
&lt;h2 id="register-the-client-and-worker">Register the client and worker&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Services&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddDaprPubSubClient&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">builder&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Services&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">AddHostedService&lt;/span>&lt;span class="p">&amp;lt;&lt;/span>&lt;span class="n">DynamicSubscriberWorker&lt;/span>&lt;span class="p">&amp;gt;();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The worker opens a subscription to a runtime-selected topic:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-csharp" data-lang="csharp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">var&lt;/span> &lt;span class="n">options&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="n">DaprSubscriptionOptions&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">new&lt;/span> &lt;span class="n">MessageHandlingPolicy&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">TimeoutDuration&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">TimeSpan&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">FromSeconds&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="m">10&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DefaultResponseAction&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">TopicResponseAction&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Retry&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">DeadLetterTopic&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="s">&amp;#34;tenant-events-dlq&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ErrorHandler&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="n">exception&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">logger&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">LogWarning&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s">&amp;#34;Subscription error: {Message}&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">exception&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">Message&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">Task&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">CompletedTask&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">};&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">await&lt;/span> &lt;span class="k">using&lt;/span> &lt;span class="nn">var&lt;/span> &lt;span class="n">subscription&lt;/span> &lt;span class="p">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">SubscribeAsync&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;pubsub&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s">&amp;#34;tenant-events&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">options&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">HandleDynamicMessageAsync&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">stoppingToken&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">await&lt;/span> &lt;span class="p">((&lt;/span>&lt;span class="n">IDaprSubscription&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="n">subscription&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="n">Completion&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">WaitAsync&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">stoppingToken&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>SubscribeAsync&lt;/code> returns an async-disposable subscription and an &lt;code>IDaprSubscription.Completion&lt;/code> task. A supervisor can await completion, log faults, delay, and open a new subscription. Always dispose the subscription and honor the host cancellation token.&lt;/p></description></item></channel></rss>