Wie erstelle ich einen benutzerdefinierten SynchronizationContext, damit alle Fortsetzungen von meiner eigenen Single-Threaded-Ereignisschleife verarbeitet werden können?
Sagen Sie, Sie schreiben eine benutzerdefinierte GUI-Bibliothek mit einem einzigen Thread (oder etwas mit einer Ereignisschleife). Nach meinem Verständnis, wenn ich @ benutasync/await
oder einfach nur regelmäßige TPL-Fortsetzungen, alle werden am @ geplaTaskScheduler.Current
(oder amSynchronizationContext.Current
).
Das Problem ist, dass die Fortsetzung möglicherweise auf die einzelnen Thread-Teile der Bibliothek zugreifen möchte, was bedeutet, dass sie in derselben Ereignisschleife ausgeführt werden muss. Bei einer einfachen Spieleschleife könnten die Ereignisse beispielsweise folgendermaßen verarbeitet werden:
// 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();
}
Jetzt ist meine Annahme richtig und TPL verwendet dasSynchronizationContext.Current
, jeder Code in der Anwendung sollte in der Lage sein, so etwas zu tun:
async void Foo() {
someLabel.Text = "Processing";
await BackgroundTask();
// This has to execute on the main thread
someLabel.Text = "Done";
}
Was bringt mich auf die Frage.Wie implementiere ich ein benutzerdefiniertesSynchronizationContext
das würde mir erlauben, Fortsetzungen auf meinem eigenen Thread zu behandeln? Ist das überhaupt der richtige Ansatz?