# RPC (/sdks/csharp/reference/rpc)



Commands and queries share `CommandMessage`/`QueryMessage` with async streaming helpers for workers.

## Commands [#commands]

### SendCommandAsync [#sendcommandasync]

```csharp
Task<CommandResponse> SendCommandAsync(CommandMessage message, CancellationToken ct = default);
```

**CommandMessage fields:**

| Property           | Type                          | Required    | Description                                          |
| ------------------ | ----------------------------- | ----------- | ---------------------------------------------------- |
| `Channel`          | `string`                      | Yes         | Target channel                                       |
| `Body`             | `ReadOnlyMemory<byte>`        | Conditional | Payload                                              |
| `Metadata`         | `string?`                     | Conditional | Metadata                                             |
| `TimeoutInSeconds` | `int?`                        | No          | RPC timeout in seconds; falls back to client default |
| `Tags`             | `Dictionary<string, string>?` | No          | Tags                                                 |

### SubscribeToCommandsAsync [#subscribetocommandsasync]

```csharp
IAsyncEnumerable<CommandReceived> SubscribeToCommandsAsync(
    CommandsSubscription subscription, CancellationToken ct = default);
```

### SendCommandResponseAsync [#sendcommandresponseasync]

```csharp
await client.SendCommandResponseAsync(CommandResponse response, CancellationToken ct = default);
```

## Queries [#queries]

### SendQueryAsync [#sendqueryasync]

```csharp
Task<QueryResponse> SendQueryAsync(QueryMessage message, CancellationToken ct = default);
```

**QueryMessage** extends `CommandMessage` with:

| Property          | Type      | Description          |
| ----------------- | --------- | -------------------- |
| `CacheKey`        | `string?` | Cache key            |
| `CacheTtlSeconds` | `int?`    | Cache TTL in seconds |

### SubscribeToQueriesAsync [#subscribetoqueriesasync]

```csharp
IAsyncEnumerable<QueryReceived> SubscribeToQueriesAsync(
    QueriesSubscription subscription, CancellationToken ct = default);
```

### SendQueryResponseAsync [#sendqueryresponseasync]

```csharp
await client.SendQueryResponseAsync(QueryResponse response, CancellationToken ct = default);
```

## Quick Usage [#quick-usage]

```csharp title="Rpc.cs"
var response = await client.SendCommandAsync(new CommandMessage
{
    Channel = "svc.commands",
    Body = payload,
    TimeoutInSeconds = 5,
});
```

## See Also [#see-also]

* [RPC Examples](/sdks/csharp/how-to/rpc/)
* [RPC pattern](/learn/rpc/getting-started)
* [C# SDK Getting Started](/sdks/csharp)
