Ich muss eine Bibliothek implementieren, um die vk.com-API anzufordern. Das Problem ist, dass die API nur 3 Anfragen pro Sekunde unterstützt. Ich möchte API asynchron haben.
Wichtig: Die API sollte den sicheren Zugriff von mehreren Threads unterstützen.
Meine Idee ist, eine Klasse namens throttler zu implementieren, die nicht mehr als 3 Requests pro Sekunde erlaubt und andere Requests verzögert.
Die Schnittstelle ist die nächste:
%Vor%Die Verwendung ist wie
%Vor%Wie wird ein Throttler implementiert?
Gegenwärtig habe ich es als Warteschlange implementiert, die von Hintergrundthread verarbeitet wird.
%Vor%Dies ist der Code der Hintergrund-Thread-Schleife, die die Warteschlange verarbeitet:
%Vor%Ist es möglich, dies ohne Hintergrund-Thread zu implementieren?
Wir beginnen also mit einer Lösung für ein einfacheres Problem: Erstellen einer Warteschlange, die gleichzeitig bis zu N Tasks verarbeiten kann, statt auf N Tasks, die pro Sekunde gestartet werden, zu drosseln und darauf aufzubauen:
%Vor% Wir verwenden auch die folgenden Hilfsmethoden, um das Ergebnis von TaskCompletionSource
mit einer 'Aufgabe:
Nun zu unserer tatsächlichen Lösung, was wir tun können, ist jedes Mal, wenn wir eine gedrosselte Operation durchführen müssen, erstellen wir TaskCompletionSource
und gehen dann in unsere TaskQueue
und fügen ein Element hinzu, das die Aufgabe startet, mit der TCS übereinstimmt Das Ergebnis erwartet es nicht und verzögert dann die Aufgabenwarteschlange für 1 Sekunde. Die Aufgabenwarteschlange lässt dann den Start einer Aufgabe erst dann zu, wenn in der letzten Sekunde keine N Aufgaben mehr gestartet wurden, während das Ergebnis der Operation selbst dem create Task
entspricht:
Hier ist eine Lösung, die eine Stoppuhr
Hier ist, wie dieser Code getestet werden kann:
%Vor%Bearbeiten: Diese Lösung funktioniert, aber nur, wenn es in Ordnung ist, alle Anfragen seriell (in einem Thread) zu bearbeiten. Andernfalls verwenden Sie die als Antwort angenommene Lösung.
Nun, dank Bester Weg in .NET, um Aufgaben in einem separaten (einzelnen) Thread zu verwalten
Meine Frage ist fast doppelt vorhanden, mit Ausnahme der Verzögerung vor der Ausführung, die eigentlich einfach ist.
Der Haupthelfer hier ist SemaphoreSlim Klasse, die es erlaubt, den Grad der Parallelität einzuschränken.
Erzeuge zuerst einen Semaphor:
%Vor%Und die finale Version von throttle sieht wie
aus %Vor%Delay-Quelle ist auch ziemlich einfach:
%Vor%Tags und Links .net c# multithreading async-await