Ich habe einen Code, der Task<T>
verwendet, der das Zurückgeben eines Ergebnisses aus einer seriellen Leseoperation für eine kurze Zeit wie folgt verzögert:
Die Idee hinter diesem Code ist, das Ergebnis zurückzugeben, wenn für ein spezifiziertes Intervall keine neuen Zeichen eingetroffen sind.
Aufgrund von Faktoren außerhalb meiner Kontrolle muss ich jedoch .NET 3.5 verwenden, was die Verwendung von Task<T>
verhindert, daher muss ich diesen Code irgendwie umgestalten.
Wie kann ich das gleiche Ergebnis erreichen, ohne Task<T>
zu benutzen?
Obwohl der spezifische Code, den ich gezeigt habe, eine zeitgesteuerte Verzögerung ist, ist meine Verwendung nicht darauf beschränkt, Dinge zu verzögern. Es kann andere Fälle geben, in denen ich eine 'lang laufende' Abfrageaufgabe sofort starten möchte. Eine typische Situation wäre beispielsweise eine E / A-gebundene Operation, bei der regelmäßig ein an die serielle Schnittstelle angeschlossenes Gerät abgefragt wird und ein Ereignis ausgelöst wird, wenn eine Bedingung erfüllt ist.
Obwohl der spezifische Code, den ich gezeigt habe, eine zeitgesteuerte Verzögerung ist, mein Die Verwendung ist nicht darauf beschränkt, Dinge zu verzögern. Es kann andere Fälle geben, in denen Ich möchte sofort eine 'lang laufende' Abfrage starten. EIN Eine typische Situation wäre beispielsweise eine E / A-gebundene Operation etwas, das periodisch ein an die serielle Schnittstelle angeschlossenes Gerät abfragt Port und dann ein Ereignis ausgelöst, wenn eine Bedingung erfüllt ist.
Ein bemerkenswerter und praktischer Hack zum Codieren solcher Szenarien mit C # 2.0 - 4.0 ist die Verwendung von selbstgesteuertem% co_de% und IEnumerable
. Es ermöglicht die Implementierung einer asynchronen Zustandsmaschine ähnlich wie yield
von C # 5.0. Auf diese Weise behalten Sie den komfortablen linearen Codefluss für Ihre asynchrone Logik. Alle C # -Sprachencode-Steueranweisungen funktionieren (außer Sie können async/await
nicht aus yield return
heraus tun).
Zum Beispiel eine Konsolen-App mit einem Timer:
%Vor% Jedes Ereignis könnte mit einem Handler umgangen werden, der try/catch
ähnlich wie der obige Timer-Callback aufruft. Der Code würde nach dem entsprechenden nextStep
beim Ereignis fortgesetzt.
Es gibt einige Implementierungen, die diesen Ansatz nutzen, zB Jeffrey Richters yield return
.
Sie können eines der folgenden in NuGet verfügbaren Pakete verwenden:
Sie können das Paket TaskParallelLibrary auf NuGet verwenden. Dieses Paket hat einen starken Namen und ist ein .NET 3.5-Back-Port der .NET-Taskbibliothek für .NET 4, die in den Reaktiven Erweiterungen enthalten war.
Sie können das System.Threading.Tasks.Unofficial -Paket verwenden NuGet. Diese alternative Implementierung verwendet die Mono-Codebasis anstelle der Microsoft-Implementierung. Beachten Sie, dass die in diesem Paket enthaltene Assembly keinen starken Namen hat. Wenn Ihre Bibliothek also starke Namen verwendet, ist dies keine Option.
Verwenden Sie ein Timer
(was tatsächlich ist, wie Delay
intern implementiert wird).
Wenn Sie bei der Bearbeitung eine asynchrone Anwendung verwenden, die auf einer asynchronen E / A-Konfiguration basiert, wird diese asynchrone E / A-Operation bereits eine Methode der Asynchronität verfügbar machen. Es könnte ein ereignisbasiertes Modell sein, es könnte einen Callback akzeptieren, es könnte IAsyncResult
verwenden usw. Task
ist ein weiterer möglicher Ansatz für die asynchrone Programmierung, und Sie sind sicherlich in der Lage, jeden Ansatz für jeden anderen Ansatz zu übersetzen , wenn Ihnen jemand vorzuziehen ist, aber im Allgemeinen neigen die Leute dazu, bei jeder Methode zu bleiben, die die zugrundeliegende IO, die sie ausführen, verwendet, es sei denn, sie haben einen zwingenden Grund, etwas anderes zu tun.
Verwenden Sie ThreadPool, um die Methode auszuführen:
Bearbeiten für Servy:
Der Standard-Scheduler für die Task Parallel Library und PLINQ verwendet das ThreadPool von .NET Framework zum Einreihen und Ausführen von Aufgaben. In .NET Framework 4 verwendet der ThreadPool die vom Typ System.Threading.Tasks.Task bereitgestellten Informationen, um die feinkörnige Parallelität (kurzlebige Arbeitseinheiten) effizient zu unterstützen, die von parallelen Aufgaben und Abfragen häufig dargestellt werden.
Edit 2 (wegen negativer Rückmeldung):
Dieser Code macht genau das, was das OP will:
%Vor%Tags und Links c# task-parallel-library asynchronous task .net-3.5