在同步 RPC 中,客户端进行远程调用,该调用返回成功或失败代码。 异步 RPC 为调用失败提供了更多机会,这些失败的处理方式不同,具体取决于发生的位置和时间。 下表描述了调用失败的方式及其处理方式。
客户端清理
| 故障症状 | 清理 |
|---|---|
| 客户端在调用远程过程时捕获异常。 | 不需要 RPC API 调用。 已清除所有 RPC 状态。 |
| 客户端收到调用完成通知,但当客户端调用 RpcAsyncCompleteCall时,它会收到错误代码。 | 不需要 RPC API 调用。 已清除所有 RPC 状态。 |
| 客户端颁发非中止或中止取消。 | 客户端必须等待通知,并在通知到达时调用 RpcAsyncCompleteCall。 |
在服务器端清理中,关键概念是交出点。 在异步调用的服务器端处理过程中,通常会对接收调用的线程执行某些处理(也称为 调度程序线程),然后(可选)调度程序线程将足够的状态放入内存块中,并发出另一个线程(也称为 工作线程)继续处理调用。 调度程序线程成功向工作线程发出信号的时刻,即工作线程称为 交出点。
服务器端清理
| 遇到错误 | 清理 |
|---|---|
| 交出点之前。 | 引发异常。 无需调用 RpcAsyncCompleteCall。 |
| 交接点后。 | 调用 RpcAsyncAbortCall;如果错误不致命,并且结果仍可返回到客户端,RpcAsyncCompleteCall。 如果 RpcAsyncCompleteCall 函数调用失败,RPC 运行时将释放参数。 用户不得访问这些参数。 调度程序线程不得执行任何可能在移交点后失败的实质性处理,因为它不再可以安全地中止调用。 具体而言,它不得在关闭点后引发异常,否则服务器可能会崩溃。 |
管道的特殊错误处理案例
使用管道时存在错误处理的特殊情况。 以下列表说明了失败的源,以及如何处理错误。
| 故障源 | 如何处理 |
|---|---|
| 客户端调用推送和调用失败。 | 不需要 RPC API 调用。 已清除所有 RPC 状态。 |
| 在管道中的耗尽之前,客户端调用 RpcAsyncCompleteCall。 | 调用失败,并显示相应的管道填充错误代码。 |
| 客户端调用拉取,调用失败。 | 不需要 RPC API 调用。 已清除所有 RPC 状态。 |
| 客户端或服务器按错误顺序调用推送或拉取。 | 运行时返回管道填充错误状态。 |
| 服务器调用推送或拉取,调用失败。 | 推送返回失败代码。 无需调用 RpcAsyncCompleteCall。 |
| 在管道耗尽之前,服务器调用 RpcAsyncCompleteCall。 | 管道调用返回管道填充错误状态。 |
| 调度后,接收作将失败。 | 下次服务器调用拉取以接收管道数据时,将返回错误。 |