【Swift/非同期】Task / DispatchQueueの優先度を確認 QOS / Priority

SwiftUI

改めて cameraQueueと Taskの整理をと思い。

AVCaptureSessionなどは順序が大事なので dispatchQueueを
他の画像処理などのタスクは非同期でできた順なのでTaskで処理しています

https://umi.grtlab.com
umi カメラというフィルム調カメラアプリの開発をしています!ぜひ使ってください!

DispatchQueueのQOS

QoS説明UI 操作への適性
.userInteractiveUI 表示や即時レスポンス向け、最優先
.userInitiatedユーザーが待っている処理向け
.default明示指定なし、システムデフォルト
.utility長時間処理、低優先×
.backgroundバックグラウンド処理向け×
let cameraQueue = DispatchQueue(label: "camera.queue",qos: .userInteractive)
cameraQueue.async {
    session.start()など
    Task { 
        後処理
    }
}

Taskの優先度一覧

優先度Swift 定義用途・説明
high / userInteractive.userInteractive / .high (TaskPriority)UI に直結する操作、即時レスポンスが必要な処理
userInitiated.userInitiatedユーザーが待っている処理(撮影・保存ボタン押下など)
default.medium / .default優先度未指定、通常処理用
utility.utility長時間かかる処理、バックグラウンド計算
background.backgroundバックグラウンドで後回しにしてよい処理(アップロード、分析など)
Task (priority: .userInitiated ) {
}

Taskはpriority指定しないと実行場所を継承するので @MainActorで実行したら

Task { @MainActor in 
}

扱いになってしまうこともあるようで(UIをブロックしてしまう.
思い処理は

Task.detached(priority:.userInitiated) {
}

detachedすると継承せずにpriority設定だそうです。

めでたし。

dispatchQueueとtaskのお互いの優先順位は関係ない呼び出し順

場所 / 方法QoS / priority 必要性実行順序への影響
DispatchQueue (serial)推奨: userInitiated / userInteractiveなし(serial 内は順番通り)
DispatchQueue (concurrent)推奨: high 優先度で UI レスポンス向上高優先の方が早く走る可能性あり
Task { … }不要(親 Task 継承)呼び出し順ほぼ順序通り
Task.detached(priority:)推奨: 重い処理を優先度指定スケジューリングのヒント、順序には影響なし
Actor / MainActor不要Actor 内順序は保証

ちょっと別の話ですが。

viewmodeiを@MainActor classにして
撮影、画像処理は core クラスにして、delegateで結果通知してUI反映しています。

delegateは nonisolated funcにして中で Task { @MainActor in で処理するのですが

Task { @MainActor in 
// 処理A
}
Task { @MainActor in 
// 処理B
}

というじょうたいで連続で処理した場合、どちらが先にスケジューリングされるかは保証されないそうです。

間に他の処理で時間が開けばほぼ問題ないようですが。
そういう連続処理や通知順序が完璧を保証するにはAsyncStreamで通知更新が良いと。

普通の処理はだいたい雰囲気で動くのですが、UI固まらないように処理を分離して頑張っています^^

https://umi.grtlab.com
umi カメラというフィルム調カメラアプリの開発をしています!ぜひ使ってください!

お気軽にコメントください!

スパム対応のためコメント認証に数日かかることがありますが、お気軽にコメントいただけると嬉しいです^^

コメント

タイトルとURLをコピーしました