カスタムシングルスレッドGUIライブラリ(またはイベントループを持つもの)を作成しているとします。私が理解したところでは、async/await
、または通常のTPL継続を使用すると、それらはすべてTaskScheduler.Current
(またはSynchronizationContext.Current
)にスケジュールされます。すべての継続を自分のシングルスレッドイベントループで処理できるようにカスタムSynchronizationContextを作成するにはどうすればよいですか?
問題は、継続がライブラリのシングルスレッド部分にアクセスしたいということです。つまり、同じイベントループで実行する必要があります。例えば、簡単なゲームループ与えられ、イベントは次のように処理される可能性があります:
// All continuation calls should be put onto this queue
Queue<Event> events;
// The main thread calls the `Update` method continuously on each "frame"
void Update() {
// All accumulated events are processed in order and the queue is cleared
foreach (var event : events) Process(event);
events.Clear();
}
は今私の仮定が正しいとTPLはSynchronizationContext.Current
を使用して、アプリケーション内の任意のコードがこのような何かを行うことができるはず与えられました
async void Foo() {
someLabel.Text = "Processing";
await BackgroundTask();
// This has to execute on the main thread
someLabel.Text = "Done";
}
これは私に質問につながります。 私は自分自身のスレッドで継続を処理できるカスタムSynchronizationContext
を実装するにはどうすればよいですか?これは正しいアプローチですか?
あなたは私よりも複雑な問題を解決しているようです。私はネスティングをしていません。フレームでは、レンダリングする単一の呼び出しを意味し、キャンバス上に単一のフレームをレンダリングします。私は他の同期のコンテキストを持っていないでしょう、ただ全体のプログラムのためのものです。私は少し物事を単純化する必要がありますか? –
@JakubArnold:はい、入れ子の部分を無視することができます。 "Exitプログラム"要求が出るまで、メインループを続けるためには、まだ 'OperationStarted'を使う必要があります。 –
しかし、これはSynchronizationContextがループを実行していると仮定しています。キューを処理するためにコンテキストを手動で呼びたいのであれば、 'Post'をオーバーライドしてキューに格納するだけで十分でしょうか? –