> For the complete documentation index, see [llms.txt](https://docs.convai.com/api-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/operation-and-stream-types.md).

# 操作与流类型

说明 Unity SDK 中所有脚本 API 共享的异步结果和流类型，以及它们解决的问题。

大多数执行异步工作的 SDK 方法会返回 `IConvaiOperation<T>` 而不是 `Task<T>`。生成连续值序列的方法会返回 `IConvaiStream<T>`。这些类型旨在与 Unity 的协程系统、C# async/await 以及基于进度的流程协同工作——而无需强制依赖于 `Task` 贯穿整个代码库。有关用法模式和代码示例，请参见 [异步模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/async-patterns.md).

***

### 为什么使用自定义异步类型？

| 要求         | `Task<T>`              | `IConvaiOperation<T>`               |
| ---------- | ---------------------- | ----------------------------------- |
| 可在协程中使用    | 没有                     | 是—— `ToCoroutine()`                 |
| 无需异常的类型化错误 | 没有                     | 是—— `Error` 属性                      |
| 进度报告       | 没有                     | 是—— `进度` 属性                         |
| 直接 `await` | 是                      | 是—— `GetAwaiter()`                  |
| 取消         | 通过 `CancellationToken` | 通过 `CancellationToken` + `Cancel()` |

***

### `IConvaiOperation<T>`

任何 SDK 异步操作的结果句柄。由以下方法返回： `ConnectAsync`, `DisconnectAsync`, `StartListeningAsync`, `WaitForCharacterReadyAsync`以及其他方法。

#### 状态属性

| 属性            | 类型                | 说明                                                     |
| ------------- | ----------------- | ------------------------------------------------------ |
| `状态`          | `OperationStatus` | 操作的当前生命周期状态                                            |
| `IsCompleted` | `bool`            | 当状态为以下值时为真： `成功`, `或`，或 `已取消`                          |
| `是否成功`        | `bool`            | 当状态为以下值时为真： `成功`                                       |
| `IsCanceled`  | `bool`            | 当状态为以下值时为真： `已取消`                                      |
| `HasError`    | `bool`            | 当状态为以下值时为真： `或`                                        |
| `Error`       | `ConvaiError`     | 在以下情况下填充： `HasError` 为真时；在成功或待处理时默认为空                  |
| `进度`          | `float`           | 完成度估计，范围为 0.0–1.0。并非所有操作都会报告细粒度进度——请检查 `状态` 以确定最终完成状态。 |

#### 异步/await

| 成员             | 说明                                                                                        |
| -------------- | ----------------------------------------------------------------------------------------- |
| `GetAwaiter()` | 返回一个 `TaskAwaiter<T>`。可让你 `await operation` 直接 await。失败时抛出 `ConvaiOperationException` 异常。 |
| `AsTask()`     | 返回底层的 `Task<T>`。当你需要传递给基于 Task 的 API 时使用，例如 `Task.WhenAll`.                               |

#### 协程

| 成员                                                                            | 说明                                                                                             |
| ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `ToCoroutine(Action<T> onSuccess = null, Action<ConvaiError> onError = null)` | 返回一个 `IEnumerator`。传递给 `StartCoroutine()`. `onSuccess` 接收结果； `onError` 如果操作失败，则接收错误。两个回调都是可选的。 |

#### 链式调用

| 成员                                                   | 说明                                                    |
| ---------------------------------------------------- | ----------------------------------------------------- |
| `ContinueWith<TNext>(Func<T, TNext> selector)`       | 同步转换。返回一个新的 `IConvaiOperation<TNext>` ，其解析结果为选择器的返回值。 |
| `ContinueWith<TNext>(Func<T, Task<TNext>> selector)` | 异步转换。返回一个新的 `IConvaiOperation<TNext>` ，当选择器任务完成时解析。   |

`ContinueWith` 会传播错误——如果源操作失败，链式操作也会以相同错误失败，而不会调用选择器。

#### 取消

| 成员         | 说明                                 |
| ---------- | ---------------------------------- |
| `Cancel()` | 请求协作式取消。操作将转换为 `已取消` ，当 SDK 确认请求时。 |

***

### `OperationStatus` 枚举

| 值         | 说明                  |
| --------- | ------------------- |
| `已创建` (0) | 操作已创建，但尚未开始         |
| `运行中` (1) | 操作正在执行              |
| `成功` (2)  | 操作已成功完成。结果可用。       |
| `或` (3)   | 操作失败。 `Error` 会被填充。 |
| `已取消` (4) | 操作在完成前被取消           |

**生命周期：** `已创建 → 运行中 → 成功 / 失败 / 已取消`

***

### `ConvaiError` 结构体

携带结构化错误信息，而无需处理异常。在 `IConvaiOperation<T>.Error` 当 `HasError` 为真时。

| 成员        | 类型       | 说明                                  |
| --------- | -------- | ----------------------------------- |
| `代码`      | `string` | 机器可读的错误代码，例如 `"connection.timeout"` |
| `Message` | `string` | 人类可读的描述                             |
| `异常`      | `异常`     | 底层异常（如果错误源于异常）。可能为 `null`.          |
| `IsEmpty` | `bool`   | 当这是默认（无错误）值时为真                      |

#### 静态工厂方法

```csharp
ConvaiError.FromException(Exception exception, string code = "exception")
```

创建一个 `ConvaiError` 从异常生成。可在自定义错误路径中使用，在从捕获的异常构造错误时。

`ConvaiError` 是一个结构体，并支持 `Equals`, `GetHashCode`，以及 `ToString()`.

***

### `ConvaiOperationException`

当你 `await` 等待一个 `IConvaiOperation<T>` 已失败的操作时抛出。继承自 `异常`.

| 属性        | 类型       | 说明                                              |
| --------- | -------- | ----------------------------------------------- |
| `代码`      | `string` | 来自底层的错误代码 `ConvaiError` ——对应 `ConvaiError.Code` |
| `Message` | `string` | 继承而来——人类可读的描述                                   |

**`HasError` 与抛出的异常对比：**

* **协程** (`ToCoroutine`）：错误会传递给 `onError` 回调。不会抛出异常。
* **异步/await**：失败的操作会抛出 `ConvaiOperationException`。使用以下方式捕获： `try/catch`.
* `HasError` 是 `true` 两种情况下都一样——无论采用哪种消费模式，你都可以随时轮询它。

{% hint style="warning" %}
使用 async/await 时， **取消会抛出 `OperationCanceledException`**，而不是 `ConvaiOperationException`。请始终同时捕获这两种异常：

```csharp
try
{
    await manager.ConnectAsync(destroyCancellationToken);
}
catch (ConvaiOperationException ex) { /* SDK error */ }
catch (OperationCanceledException)  { /* canceled   */ }
```

{% endhint %}

***

### `IConvaiStream<T>`

由随时间产生连续值序列的方法返回，例如流式转录 token 或流式音频帧。实现 `IAsyncDisposable`.

#### 属性

| 属性      | 类型            | 说明                   |
| ------- | ------------- | -------------------- |
| `状态`    | `流状态`         | 流的当前生命周期状态           |
| `Error` | `ConvaiError` | 在以下情况下填充： `状态` 是 `或` |

#### 方法

| 方法                                             | 返回                    | 说明                                 |
| ---------------------------------------------- | --------------------- | ---------------------------------- |
| `ReadAllAsync(CancellationToken ct = default)` | `IAsyncEnumerable<T>` | 在项目到达时逐个产出。流结束时完成。支持取消。            |
| `DisposeAsync()`                               | `ValueTask`           | 释放流并释放资源。始终通过以下方式调用 `await using`. |

```csharp
await using var stream = GetSomeStream();
await foreach (var item in stream.ReadAllAsync(destroyCancellationToken))
{
    ProcessItem(item);
}
```

***

### `流状态` 枚举

| 值           | 说明                   |
| ----------- | -------------------- |
| `已创建` (0)   | 流已创建，但尚未开始流式传输       |
| `流式传输中` (1) | 流正在主动产出项目            |
| `已完成` (2)   | 所有项目均已传递；流已正常结束      |
| `或` (3)     | 流遇到错误。 `Error` 会被填充。 |
| `已取消` (4)   | 流在完成前被取消             |

**生命周期：** `已创建 → 流式传输中 → 已完成 / 失败 / 已取消`

***

### `Unit` 结构体

```csharp
Unit.Value // 唯一实例
```

在操作没有有意义的返回值时，作为类型参数使用的相当于 void 的类型。诸如以下操作 `DisconnectAsync()` 和 `StopListeningAsync()` 返回 `IConvaiOperation<Unit>` — `await` 它们，目的是副作用，而不是结果。

`Unit` 支持相等比较（`==`, `!=`, `Equals`）和 `ToString()` 返回 `"()"`.

***

### 下一步

使用这些类型的实用消费模式，请参见 [异步模式](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/async-patterns.md)。对于所有返回 `IConvaiOperation<T>`的 SDK 方法，请参阅 [ConvaiManager API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/convaimanager-api.md) 和 [角色与玩家 API](/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/character-and-player-api.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.convai.com/api-docs/zh/cha-jian-yu-ji-cheng/convai-unity-sdk/scripting-reference/operation-and-stream-types.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
