Skip to content

Yield

1. 概要

Yield は、現在の同期的な処理では発行せず、いったん実行を後続の非同期処理へ譲ってから Unit を 1 つ発行して完了するファクトリメソッドです。

既定では ThreadPool に処理をキューイングし、購読呼び出しとは別のタイミングで通知します。TimeProvider を指定した場合は、その TimeProvider の 0 秒タイマーを使って次のコールバックタイミングで通知します。

フレームの概念がない環境(サーバーサイド、コンソールアプリなど)で、同期的な発行を避けて処理を一度非同期に逃がしたい場合に使用します。

2. シグネチャ

基本

csharp
public static Observable<Unit> Yield(CancellationToken cancellationToken = default)

既定のスケジューリングを使用して、購読呼び出しとは別のタイミングで Unit を発行し完了します。

csharp
Observable.Yield()

TimeProvider 指定

csharp
public static Observable<Unit> Yield(TimeProvider timeProvider, CancellationToken cancellationToken = default)

使用する TimeProvider を明示的に指定するオーバーロードです。

csharp
Observable.Yield(TimeProvider.System)

オーバーロードの使い分け

overload使う場面
Yield()既定のスケジューリングで非同期に発行する
Yield(TimeProvider)カスタム TimeProvider を使用する

3. マーブルダイアグラム

Yield のマーブルダイアグラム

購読すると、現在の同期処理では発行せず、後続の非同期タイミングで Unit を 1 つ発行し、直後に完了通知を送ります。

4. サンプルコード

csharp
using R3;

// 現在の同期処理を抜けたあとに 1 回だけ発行
Observable.Yield()
    .Subscribe(
        _ => Console.WriteLine("非同期タイミングで実行"),
        _ => Console.WriteLine("完了"));
// 出力(後続の非同期タイミング): 非同期タイミングで実行
// 出力: 完了

// TimeProvider を指定
Observable.Yield(TimeProvider.System)
    .Subscribe(_ => Console.WriteLine("非同期で実行"));

// Concat で順次遅延を挿入
Observable.Yield()
    .Select(_ => "step 1")
    .Concat(Observable.Yield().Select(_ => "step 2"))
    .Subscribe(x => Console.WriteLine(x));
// 出力:
// step 1
// step 2

5. 補足

NextFrame との違い

NextFrame はフレームベースの遅延(FrameProvider)で次のフレームに遅延します。Yield はフレーム番号ではなく、ThreadPool または TimeProvider の次のコールバックタイミングへ処理を譲ります。フレームの概念がない環境では Yield を、ゲームエンジンなどでフレーム境界をまたぎたい場合は NextFrame を使用してください。

YieldFrame との違い

YieldFrameYield のフレームベース版です。Yield は ThreadPool または TimeProvider のコールバックへ処理を譲り、YieldFrameFrameProvider のフレーム処理へ譲ります。